From ee127821ef22bc12e36f8096db0ed44800366560 Mon Sep 17 00:00:00 2001 From: Danilo Guanabara Date: Sun, 12 Dec 2021 17:01:26 -0300 Subject: [PATCH 1/4] Fixed linking issue --- Cargo.toml | 15 +- build.rs | 1 + examples/csharp/Program.cs | 25 +- examples/csharp/run.sh | 2 +- src/bindings/client.rs | 2 +- src/bindings/client/coinbase.rs | 9 +- src/bindings/environment.rs | 18 ++ src/bindings/string/mod.rs | 23 +- src/bindings/string/string.methods.cs | 11 +- tests/apis/binance/account.rs | 282 ----------------- tests/apis/binance/general.rs | 47 --- tests/apis/binance/market.rs | 121 -------- tests/apis/binance/mod.rs | 4 - tests/apis/binance/websocket.rs | 92 ------ tests/apis/coinbase/account.rs | 423 -------------------------- tests/apis/coinbase/market.rs | 144 --------- tests/apis/coinbase/mod.rs | 3 - tests/apis/coinbase/websocket.rs | 61 ---- tests/apis/mod.rs | 2 - tests/old_nash_tests/account.rs | 279 ----------------- tests/old_nash_tests/market.rs | 110 ------- tests/old_nash_tests/mod.rs | 3 - tests/old_nash_tests/websocket.rs | 156 ---------- 23 files changed, 51 insertions(+), 1782 deletions(-) delete mode 100644 tests/apis/binance/account.rs delete mode 100644 tests/apis/binance/general.rs delete mode 100644 tests/apis/binance/market.rs delete mode 100644 tests/apis/binance/mod.rs delete mode 100644 tests/apis/binance/websocket.rs delete mode 100644 tests/apis/coinbase/account.rs delete mode 100644 tests/apis/coinbase/market.rs delete mode 100644 tests/apis/coinbase/mod.rs delete mode 100644 tests/apis/coinbase/websocket.rs delete mode 100644 tests/apis/mod.rs delete mode 100644 tests/old_nash_tests/account.rs delete mode 100644 tests/old_nash_tests/market.rs delete mode 100644 tests/old_nash_tests/mod.rs delete mode 100644 tests/old_nash_tests/websocket.rs diff --git a/Cargo.toml b/Cargo.toml index 7f9c191f..537a2313 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ path = "examples/rust/orderbook.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -# bindings = ["ligen", "ligen-macro", "ligen-csharp"] +bindings = ["ligen", "ligen-macro", "ligen-csharp"] default = ["rust_gmp"] rust_gmp = ["openlimits-nash/rust_gmp"] num_bigint = ["openlimits-nash/num_bigint"] @@ -25,16 +25,17 @@ openlimits-binance = "0.3.0" openlimits-exchange = "0.3.0" openlimits-coinbase = "0.3.0" openlimits-nash = "0.3.0" -# ligen-macro = { path = "../../sensorial/systems/ligen/ligen/macro", optional = true } -# ligen = { path = "../../sensorial/systems/ligen/ligen", optional = true } -# lazy_static = "1.4.0" +ligen-macro = { path = "../../sensorial/systems/ligen/ligen/macro", optional = true } +ligen = { path = "../../sensorial/systems/ligen/ligen", optional = true } +lazy_static = "1.4.0" +rust_decimal = "1.17.0" +tokio = { version = "1.0", features = ["full"] } [dev-dependencies] rust_decimal = "1.14.3" -tokio = { version = "1.0", features = ["full"] } futures = "0.3" dotenv = "0.15.0" [build-dependencies] -# ligen = { path = "../../sensorial/systems/ligen/ligen", optional = true } -# ligen-csharp = { path = "../../sensorial/systems/ligen/generators/ligen-csharp", optional = true } \ No newline at end of file +ligen = { path = "../../sensorial/systems/ligen/ligen", optional = true } +ligen-csharp = { path = "../../sensorial/systems/ligen/generators/ligen-csharp", optional = true } \ No newline at end of file diff --git a/build.rs b/build.rs index 86c289f6..1bb8cdfe 100644 --- a/build.rs +++ b/build.rs @@ -7,6 +7,7 @@ fn main() { match Project::current() { Ok(project) => { + println!("Generating C# bindings..."); let csharp_generator = CSharpGenerator::default(); csharp_generator.generate(&project).expect("Failed to generate C# bindings."); }, diff --git a/examples/csharp/Program.cs b/examples/csharp/Program.cs index 7b1a5445..cab4ab62 100644 --- a/examples/csharp/Program.cs +++ b/examples/csharp/Program.cs @@ -10,26 +10,21 @@ class Program { static public void Main(string[] args) { - var ffi_string = Client.FFIGetName(); - Console.WriteLine(ffi_string); -// var ptr = FFIString.FFIGetPointer(ffi_string); -// Console.WriteLine(ptr); - return; + Console.WriteLine("String: " + Client.GetName()); CoinbaseParameters parameters = new CoinbaseParameters(Environment.Production, "a", "b", "c"); - string key = parameters.apiKey; Client client = Client.Coinbase(parameters); // Console.WriteLine(Decimal.Parse(askBid.qty)); // Console.WriteLine(Decimal.Parse(askBid.qty)); // Console.WriteLine(askBid.price); - var list = new List(); - list.Add(1); - list.Add(2); - list.Add(3); - Console.WriteLine(client.Sum(list)); - var result = client.Mul(list, 2); - foreach (var value in result) { - Console.WriteLine(value); - } +// var list = new List(); +// list.Add(1); +// list.Add(2); +// list.Add(3); +// Console.WriteLine(client.Sum(list)); +// var result = client.Mul(list, 2); +// foreach (var value in result) { +// Console.WriteLine(value); +// } // Test.Display(person); // NashClientConfig config = NashClientConfig.Unauthenticated(0, NashEnvironment.Production, 1000); diff --git a/examples/csharp/run.sh b/examples/csharp/run.sh index 6f622285..6679eaa2 100755 --- a/examples/csharp/run.sh +++ b/examples/csharp/run.sh @@ -1,5 +1,5 @@ # cargo build --manifest-path ../../Cargo.toml -cp ../../target/ligen/openlimits/lib/openlimits.dll ./bin/Debug/netcoreapp5.0/openlimits_csharp.dll +cp ../../target/ligen/ffi/openlimits/target/release/ffi_openlimits.dll ./bin/Debug/netcoreapp5.0/ffi_openlimits.dll # cp ../../target/ligen/openlimits/lib/libopenlimits.so ./bin/Debug/netcoreapp5.0/libopenlimits_csharp.so dotnet run diff --git a/src/bindings/client.rs b/src/bindings/client.rs index 58231e57..71ff0c89 100644 --- a/src/bindings/client.rs +++ b/src/bindings/client.rs @@ -1,6 +1,6 @@ use runtime::RUNTIME; +use openlimits_coinbase::{Coinbase, CoinbaseParameters}; -use crate::{Coinbase, CoinbaseParameters}; // use crate::prelude::*; pub mod coinbase; diff --git a/src/bindings/client/coinbase.rs b/src/bindings/client/coinbase.rs index e5710585..0ef70485 100644 --- a/src/bindings/client/coinbase.rs +++ b/src/bindings/client/coinbase.rs @@ -1,6 +1,6 @@ use crate::bindings::string::FFIString; use crate::bindings::environment::Environment; -use crate::{CoinbaseParameters, CoinbaseCredentials}; +use openlimits_coinbase::{CoinbaseParameters, CoinbaseCredentials}; use ligen::marshalling::MarshalFrom; use ligen_macro::inner_ligen; @@ -30,10 +30,6 @@ pub struct FFICoinbaseParameters { impl MarshalFrom for CoinbaseParameters { fn marshal_from(from: FFICoinbaseParameters) -> Self { - let sandbox = match from.environment { - Environment::Sandbox => true, - _ => false - }; let api_key = String::marshal_from(from.apiKey); let api_secret = String::marshal_from(from.apiSecret); let passphrase = String::marshal_from(from.passphrase); @@ -42,6 +38,7 @@ impl MarshalFrom for CoinbaseParameters { } else { None }; - Self { sandbox, credentials } + let environment = from.environment.into(); + Self { environment, credentials } } } \ No newline at end of file diff --git a/src/bindings/environment.rs b/src/bindings/environment.rs index 452cb3f2..f77fb901 100644 --- a/src/bindings/environment.rs +++ b/src/bindings/environment.rs @@ -3,3 +3,21 @@ pub enum Environment { Sandbox, Production } + +impl From for Environment { + fn from(from: openlimits_exchange::exchange::Environment) -> Self { + match from { + openlimits_exchange::exchange::Environment::Sandbox => Environment::Sandbox, + openlimits_exchange::exchange::Environment::Production => Environment::Production + } + } +} + +impl From for openlimits_exchange::exchange::Environment { + fn from(from: Environment) -> Self { + match from { + Environment::Sandbox => openlimits_exchange::exchange::Environment::Sandbox, + Environment::Production => openlimits_exchange::exchange::Environment::Production + } + } +} \ No newline at end of file diff --git a/src/bindings/string/mod.rs b/src/bindings/string/mod.rs index 5673d34e..6a3f51b8 100644 --- a/src/bindings/string/mod.rs +++ b/src/bindings/string/mod.rs @@ -28,31 +28,12 @@ inner_ligen! { ) ), ) - - // csharp( - // marshal( - // FFIString( - // name = "string", - // MarshalAs = "UnmanagedType.LPStr" - // ), - // String( - // name = "string", - // MarshalAs = "UnmanagedType.LPStr" - // ) - // ), - // ) } pub struct FFIString { string: CString } -impl Drop for FFIString { - fn drop(&mut self) { - println!("Why is {} being dropped?", self.get_pointer() as u64); - } -} - impl FFIString { pub fn new(pointer: *mut i8) -> Self { let string = unsafe { @@ -62,9 +43,7 @@ impl FFIString { } pub fn get_pointer(&self) -> *const i8 { - let ptr = self.string.as_ptr(); - println!("ptr: {} of {}", ptr as u64, self.string.to_string_lossy()); - ptr + self.string.as_ptr() } } diff --git a/src/bindings/string/string.methods.cs b/src/bindings/string/string.methods.cs index 925d1229..d1d44cc8 100644 --- a/src/bindings/string/string.methods.cs +++ b/src/bindings/string/string.methods.cs @@ -6,7 +6,12 @@ public static implicit operator string(FFIString from) { public static implicit operator FFIString(string from) { unsafe { - return new FFIString(Marshal.StringToHGlobalAnsi(from)); - // FIXME: Memory leak https://docs.microsoft.com/pt-br/dotnet/api/system.runtime.interopservices.marshal.freehglobal?view=net-5.0 + return FFIString.New(Marshal.StringToHGlobalAnsi(from)); } - } \ No newline at end of file + } + + public static implicit operator IntPtr(FFIString from) { + unsafe { + return from.GetPointer(); + } + } diff --git a/tests/apis/binance/account.rs b/tests/apis/binance/account.rs deleted file mode 100644 index 0691c437..00000000 --- a/tests/apis/binance/account.rs +++ /dev/null @@ -1,282 +0,0 @@ -use dotenv::dotenv; -use rust_decimal::prelude::Decimal; -use std::env; - -use openlimits::{ - exchange::binance::{ - model::{AllOrderReq, TimeInForce, TradeHistoryReq}, - Binance, BinanceCredentials, BinanceParameters, - }, - prelude::*, -}; -use openlimits::model::GetPriceTickerRequest; -use openlimits::exchange::binance::model::Order; - -#[tokio::test] -async fn get_account() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_account() - .await - .expect("Couldn't get account"); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_balance() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_balance("BTC") - .await - .expect("Couldn't get balance."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_open_orders() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_open_orders("BNBBTC") - .await - .expect("Couldn't get open orders."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_open_orders() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_all_open_orders() - .await - .expect("Couldn't get all open orders."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_orders() { - let exchange = init().await; - let params = AllOrderReq { - paginator: None, - symbol: String::from("BNBBTC"), - }; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_all_orders(¶ms) - .await - .expect("Couldn't get all orders."); - println!("{:?}", resp); -} - -async fn get_price(exchange: &Binance, pair: &str) -> Decimal { - let market_pair = pair.to_string(); - let get_price_ticker_request = GetPriceTickerRequest { market_pair }; - let ticker = exchange - .get_price_ticker(&get_price_ticker_request) - .await - .expect("Couldn't get ticker."); - ticker - .price - .expect("Couldn't get price.") -} - -async fn place_limit_sell(exchange: &Binance, time_in_force: TimeInForce) -> Order { - let pair = exchange - .get_pair("BNBBTC") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let price = get_price(&exchange, "BNBBTC").await; - exchange - .inner_client() - .expect("Couldn't get inner time.") - .limit_sell( - pair, - Decimal::new(1, 1), - price, - time_in_force, - false, - ) - .await - .expect("Couldn't limit sell.") -} - -#[tokio::test] -async fn get_order() { - let exchange = init().await; - let transaction = place_limit_sell(&exchange, TimeInForce::GTC).await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .get_order("BNBBTC", transaction.order_id) - .await - .expect("Couldn't get order."); - println!("{:?}", resp); -} - - -#[tokio::test] -#[ignore] -async fn limit_buy() { - let pair_text = "BNBBUSD"; - let exchange = init().await; - let pair = exchange - .get_pair(pair_text) - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let price = get_price(&exchange, pair_text).await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .limit_buy( - pair, - Decimal::new(1, 1), - price, - TimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit buy."); - println!("{:?}", resp); -} - -#[tokio::test] -#[ignore] -async fn rounded_limit_buy() { - let pair_text = "BNBBUSD"; - let exchange = init().await; - let pair = exchange - .get_pair(pair_text) - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let price = get_price(&exchange, pair_text).await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .limit_buy( - pair, - Decimal::new(12345678, 8), - price, - TimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit buy."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell() { - let exchange = init().await; - let resp = place_limit_sell(&exchange, TimeInForce::GTC).await; - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell_fok() { - let exchange = init().await; - let resp = place_limit_sell(&exchange, TimeInForce::FOK).await; - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell_ioc() { - let exchange = init().await; - let resp = place_limit_sell(&exchange, TimeInForce::IOC).await; - println!("{:?}", resp); -} - -#[tokio::test] -#[ignore] -async fn market_buy() { - let pair_text = "BNBBUSD"; - let exchange = init().await; - let pair = exchange - .get_pair(pair_text) - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .market_buy(pair, Decimal::new(1, 2)) - .await - .expect("Couldn't market buy."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn market_sell() { - let exchange = init().await; - let pair = exchange - .get_pair("BNBBTC") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .market_sell(pair, Decimal::new(1, 0)) - .await - .expect("Couldn't market sell."); - - println!("{:?}", resp); -} - -#[tokio::test] -async fn cancel_order() { - let exchange = init().await; - let transaction = place_limit_sell(&exchange, TimeInForce::GTC).await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .cancel_order("BNBBTC", transaction.order_id) - .await - .expect("Couldn't cancel order."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn trade_history() { - let exchange = init().await; - let params = TradeHistoryReq { - paginator: None, - symbol: String::from("BNBBTC"), - }; - - let resp = exchange - .inner_client() - .expect("Couldn't get inner time.") - .trade_history(¶ms) - .await - .expect("Couldn't trade history."); - println!("{:?}", resp); -} - -async fn init() -> Binance { - dotenv().ok(); - Binance::new(BinanceParameters { - sandbox: true, - credentials: Some(BinanceCredentials { - api_key: env::var("BINANCE_API_KEY").expect("Couldn't get environment variable"), - api_secret: env::var("BINANCE_API_SECRET").expect("Couldn't get environment variable"), - }), - }) - .await - .expect("Failed to create Client") -} diff --git a/tests/apis/binance/general.rs b/tests/apis/binance/general.rs deleted file mode 100644 index f4085e7a..00000000 --- a/tests/apis/binance/general.rs +++ /dev/null @@ -1,47 +0,0 @@ -use openlimits::{ - exchange::binance::{Binance, BinanceParameters}, - prelude::*, -}; - -#[tokio::test] -async fn ping() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - assert_eq!( - "pong", - exchange - .inner_client() - .expect("Couldn't get inner client.") - .ping() - .await - .expect("Couldn't ping.") - ); -} - -#[tokio::test] -async fn get_server_time() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_server_time() - .await - .expect("Couldn't get server time."); -} - -#[tokio::test] -async fn get_exchange_info() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_exchange_info() - .await - .expect("Couldn't get openlimits-exchange info."); - println!("{:?}", resp); -} diff --git a/tests/apis/binance/market.rs b/tests/apis/binance/market.rs deleted file mode 100644 index 343cfb72..00000000 --- a/tests/apis/binance/market.rs +++ /dev/null @@ -1,121 +0,0 @@ -use openlimits::{ - exchange::binance::{model::KlineParams, Binance, BinanceParameters}, - prelude::*, -}; - -#[tokio::test] -async fn get_depth() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_depth("BNBBTC", 50) - .await - .expect("Couldn't get depth."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_prices() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_all_prices() - .await - .expect("Couldn't get all prices."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_price() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_price("BNBBTC") - .await - .expect("Couldn't get price."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_book_tickers() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_all_book_tickers() - .await - .expect("Couldn't get all book tickers."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_book_ticker() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_book_ticker("BNBBTC") - .await - .expect("Couldn't get book ticker."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_24h_price_stats() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_24h_price_stats("BNBBTC") - .await - .expect("Couldn't get 24h price stats."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_klines() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let params = KlineParams { - symbol: String::from("BNBBTC"), - interval: String::from("5m"), - paginator: None, - }; - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_klines(¶ms) - .await - .expect("Couldn't get klines."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_24h_price_stats_all() { - let exchange = Binance::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client"); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_24h_price_stats_all() - .await - .expect("Couldn't get 24h price stats all."); - println!("{:?}", resp); -} diff --git a/tests/apis/binance/mod.rs b/tests/apis/binance/mod.rs deleted file mode 100644 index b18d6f38..00000000 --- a/tests/apis/binance/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod account; -mod general; -mod market; -mod websocket; diff --git a/tests/apis/binance/websocket.rs b/tests/apis/binance/websocket.rs deleted file mode 100644 index 674a834a..00000000 --- a/tests/apis/binance/websocket.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::sync::mpsc::sync_channel; - -use openlimits::{ - exchange::binance::{ - BinanceParameters, client::websocket::BinanceWebsocket, - model::websocket::BinanceSubscription, - }, -}; -use openlimits::exchange::traits::stream::ExchangeWs; - -async fn test_subscription_callback(websocket: BinanceWebsocket, sub: BinanceSubscription) { - let (tx, rx) = sync_channel(0); - - websocket - .subscribe(sub, move |m| { - m.as_ref().expect("Couldn't get response."); - tx.send(()).expect("Couldn't send sync message."); - }) - .await - .expect("Couldn't subscribe."); - - rx.recv().expect("Couldn't receive sync message."); -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn aggregate_trade() { - let websocket = init().await; - let sub = BinanceSubscription::AggregateTrade("bnbbtc".to_string()); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn candlestick() { - let websocket = init().await; - let sub = BinanceSubscription::Candlestick("bnbbtc".to_string(), "1m".to_string()); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn depth() { - let websocket = init().await; - let sub = BinanceSubscription::Depth("bnbbtc".to_string(), Some(1)); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn mini_ticker() { - let websocket = init().await; - let sub = BinanceSubscription::MiniTicker("bnbbtc".to_string()); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn mini_ticker_all() { - let websocket = init().await; - let sub = BinanceSubscription::MiniTickerAll; - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn order_book() { - let websocket = init().await; - let sub = BinanceSubscription::OrderBook("bnbbtc".to_string(), 10); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn ticker() { - let websocket = init().await; - let sub = BinanceSubscription::Ticker("bnbbtc".to_string()); - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn ticker_all() { - let websocket = init().await; - let sub = BinanceSubscription::TickerAll; - test_subscription_callback(websocket, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn trade() { - let websocket = init().await; - let sub = BinanceSubscription::Trade("bnbbtc".to_string()); - test_subscription_callback(websocket, sub).await; -} - -async fn init() -> BinanceWebsocket { - BinanceWebsocket::new(BinanceParameters::sandbox()) - .await - .expect("Failed to create Client") -} diff --git a/tests/apis/coinbase/account.rs b/tests/apis/coinbase/account.rs deleted file mode 100644 index c0828937..00000000 --- a/tests/apis/coinbase/account.rs +++ /dev/null @@ -1,423 +0,0 @@ -use dotenv::dotenv; -use rust_decimal::prelude::Decimal; -use std::env; - -use openlimits::{ - exchange::coinbase::{ - model::{CancelAfter, GetFillsReq, GetOrderRequest, OrderTimeInForce}, - Coinbase, CoinbaseCredentials, CoinbaseParameters, - }, - prelude::*, -}; - -#[tokio::test] -async fn get_account() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_account(None) - .await - .expect("Couldn't get account."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_open_orders() { - let exchange = init().await; - let params = GetOrderRequest { - status: Some(String::from("open")), - paginator: None, - product_id: None, - }; - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_orders(Some(¶ms)) - .await - .expect("Couldn't get orders."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_all_orders() { - let exchange = init().await; - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_orders(None) - .await - .expect("Couldn't get orders."); - println!("{:?}", resp); - - // let params = GetOrderRequest{ - // status: Some(String::from("open")), - // paginator: None, - // product_id: None - // }; -} - -#[tokio::test] -async fn get_all_orders_for_a_given_product() { - let exchange = init().await; - - let params = GetOrderRequest { - status: None, - paginator: None, - product_id: Some(String::from("ETH-BTC")), - }; - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_orders(Some(¶ms)) - .await - .expect("Couldn't get orders."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_order() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let order = exchange - .inner_client() - .expect("Couldn't get inner client.") - .market_buy(pair, Decimal::new(1, 3)) - .await - .expect("Couldn't market buy."); - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_order(order.id) - .await - .expect("Couldn't get order."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_buy() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_buy( - pair, - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit buy."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair, - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit sell."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell_fok() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair, - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::FOK, - false, - ) - .await - .expect("Couldn't limit sell."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell_ioc() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair, - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::IOC, - false, - ) - .await - .expect("Couldn't limit sell."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn limit_sell_gtt() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair, - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::GTT { - cancel_after: CancelAfter::Day, - }, - false, - ) - .await - .expect("Couldn't limit sell."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn market_buy() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .market_buy(pair, Decimal::new(1, 3)) - .await - .expect("Couldn't market buy."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn market_sell() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .market_sell(pair, Decimal::new(1, 3)) - .await - .expect("Couldn't market sell."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn cancel_all_orders() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair.clone(), - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit sell."); - exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair.clone(), - Decimal::new(1, 3), - Decimal::new(1000, 0), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit sell."); - - exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_buy( - pair, - Decimal::new(2, 2), - Decimal::new(2, 2), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit buy."); - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .cancel_all_orders(Some("BTC-USD")) - .await - .expect("Couldn't cancel all orders."); - - println!("{:?}", resp); - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .cancel_all_orders(None) - .await - .expect("Couldn't cancel all orders."); - - println!("{:?}", resp); -} - -#[tokio::test] -async fn cancel_order() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read handle."); - let order = exchange - .inner_client() - .expect("Couldn't get inner client.") - .limit_sell( - pair, - Decimal::new(1, 3), - Decimal::new(100000, 0), - OrderTimeInForce::GTC, - false, - ) - .await - .expect("Couldn't limit sell."); - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .cancel_order(order.id, Some("BTC-USD")) - .await - .expect("Couldn't cancel order."); - - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_fills_for_order() { - let exchange = init().await; - let pair = exchange - .get_pair("BTC-USD") - .await - .expect("Couldn't get pair handle.") - .read() - .expect("Couldn't read pair."); - let order = exchange - .inner_client() - .expect("Couldn't get inner client.") - .market_sell(pair, Decimal::new(1, 3)) - .await - .expect("Couldn't market sell."); - - let params = GetFillsReq { - order_id: Some(order.id), - product_id: None, - paginator: None, - }; - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_fills(Some(¶ms)) - .await - .expect("Couldn't get fills."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_fills_for_product() { - let exchange = init().await; - - let params = GetFillsReq { - order_id: None, - product_id: Some(String::from("BTC-USD")), - paginator: None, - }; - - let resp = exchange - .inner_client() - .expect("Couldn't get inner client.") - .get_fills(Some(¶ms)) - .await - .expect("Couldn't get fills."); - println!("{:?}", resp); -} - -async fn init() -> Coinbase { - dotenv().ok(); - Coinbase::new(CoinbaseParameters { - sandbox: true, - credentials: Some(CoinbaseCredentials { - api_key: env::var("COINBASE_API_KEY").expect("Couldn't get environment varilable."), - api_secret: env::var("COINBASE_API_SECRET") - .expect("Couldn't get environment varilable."), - passphrase: env::var("COINBASE_PASSPHRASE") - .expect("Couldn't get environment varilable."), - }), - }) - .await - .expect("Failed to create Client") -} diff --git a/tests/apis/coinbase/market.rs b/tests/apis/coinbase/market.rs deleted file mode 100644 index a9dae492..00000000 --- a/tests/apis/coinbase/market.rs +++ /dev/null @@ -1,144 +0,0 @@ -use chrono::naive::NaiveDateTime; -use openlimits::{ - exchange::coinbase::{ - model::{BookRecordL1, CandleRequestParams, DateRange, Paginator}, - Coinbase, CoinbaseParameters, - }, - prelude::*, -}; - -#[tokio::test] -async fn products() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .products() - .await - .expect("Couldn't get products."); - println!("{:?}", res); -} - -#[tokio::test] -async fn product() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .product("BTC-USD") - .await - .expect("Couldn't get product."); - println!("{:?}", res); -} - -#[tokio::test] -#[ignore] -async fn trades() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .trades("BTC-USD", None) - .await - .expect("Couldn't get trades."); - println!("{:?}", res); - - let trade = res.last().expect("Couldn't get last trade."); - - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .trades( - "BTC-USD", - Some(&Paginator { - after: Some(trade.trade_id), - limit: Some(10), - before: None, - }), - ) - .await - .expect("Couldn't get trades."); - println!("{:?}", res); -} - -#[tokio::test] -async fn book() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .book::("BTC-USD") - .await - .expect("Couldn't get book."); - println!("{:?}", res); -} - -#[tokio::test] -async fn ticker() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .ticker("BTC-USD") - .await - .expect("Couldn't get ticker."); - println!("{:?}", res); -} - -#[tokio::test] -async fn candles() { - let exchange = Coinbase::new(CoinbaseParameters::sandbox()) - .await - .expect("Failed to create Client"); - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .candles("BTC-USD", None) - .await - .expect("Couldn't get candles."); - println!("{:?}", res); - - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .candles( - "BTC-USD", - Some(&CandleRequestParams { - granularity: Some(60), - daterange: None, - }), - ) - .await - .expect("Couldn't get candles."); - println!("{:?}", res); - let date = - NaiveDateTime::parse_from_str("2020-08-20T00:00:00.642366Z", "%Y-%m-%dT%H:%M:%S.%fZ") - .expect("Couldn't parse date from string."); - - let res = exchange - .inner_client() - .expect("Couldn't get inner client.") - .candles( - "BTC-USD", - Some(&CandleRequestParams { - granularity: Some(3600), - daterange: Some(DateRange { - start: Some(date), - end: None, - }), - }), - ) - .await - .expect("Couldn't get candles."); - println!("{:?}", res); -} diff --git a/tests/apis/coinbase/mod.rs b/tests/apis/coinbase/mod.rs deleted file mode 100644 index b66643a7..00000000 --- a/tests/apis/coinbase/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod account; -mod market; -mod websocket; diff --git a/tests/apis/coinbase/websocket.rs b/tests/apis/coinbase/websocket.rs deleted file mode 100644 index 53d400de..00000000 --- a/tests/apis/coinbase/websocket.rs +++ /dev/null @@ -1,61 +0,0 @@ -use openlimits::exchange::coinbase::{ - client::websocket::CoinbaseWebsocket, model::websocket::CoinbaseSubscription, - CoinbaseParameters, -}; -use openlimits::exchange::traits::stream::ExchangeWs; -use openlimits::model::websocket::{OpenLimitsWebSocketMessage, WebSocketResponse}; -use std::sync::mpsc::sync_channel; -use std::time::Duration; - -async fn test_subscription_callback( - websocket: CoinbaseWebsocket, - sub: CoinbaseSubscription, - expected_messages: Vec, -) { - let (tx, rx) = sync_channel(0); - - let mut received_messages: Vec = expected_messages.iter().map(|_| false).collect(); - - websocket - .subscribe(sub, move |message| { - if let Ok(message) = message.as_ref() { - if let WebSocketResponse::Generic(message) = message { - let expected_iter = expected_messages.iter().map(|expected| { - std::mem::discriminant(expected) == std::mem::discriminant(&message) - }); - for (already_received, currently_received) in - received_messages.iter_mut().zip(expected_iter) - { - if !*already_received { - *already_received = currently_received; - } - } - if received_messages.iter().all(|received| *received) { - tx.send(()).expect("Couldn't send sync message."); - } - } - } - }) - .await - .expect("Couldn't subscribe."); - rx.recv_timeout(Duration::from_secs(3)) - .expect("Couldn't receive sync message."); -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn order_book() { - let websocket = init().await; - let sub = CoinbaseSubscription::Level2("BTC-USD".to_string()); - let expected = vec![ - OpenLimitsWebSocketMessage::OrderBook(Default::default()), - OpenLimitsWebSocketMessage::OrderBookDiff(Default::default()), - ]; - test_subscription_callback(websocket, sub, expected).await; -} - -async fn init() -> CoinbaseWebsocket { - CoinbaseWebsocket::new(CoinbaseParameters { - sandbox: true, - credentials: None, - }) -} diff --git a/tests/apis/mod.rs b/tests/apis/mod.rs deleted file mode 100644 index a62b3d7c..00000000 --- a/tests/apis/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -// mod openlimits-binance; -mod coinbase; diff --git a/tests/old_nash_tests/account.rs b/tests/old_nash_tests/account.rs deleted file mode 100644 index 2b1deba2..00000000 --- a/tests/old_nash_tests/account.rs +++ /dev/null @@ -1,279 +0,0 @@ -use chrono::Duration; -use dotenv::dotenv; -use nash_native_client::Environment; -use openlimits::{ - OpenLimits, - prelude::*, - model::OpenMarketOrderRequest, - model::{ - CancelAllOrdersRequest, CancelOrderRequest, GetOrderHistoryRequest, OpenLimitOrderRequest, - TimeInForce, TradeHistoryRequest, - }, - exchange::nash::Nash, - exchange::nash::NashCredentials, - exchange::nash::NashParameters, -}; -use rust_decimal::prelude::{Decimal, FromStr}; -use std::env; -use std::time::Duration as NativeDuration; - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _limit_buy() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillCancelled, - price: Decimal::from_str("100.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.10000").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let resp = exchange - .limit_buy(&req) - .await - .expect("Couldn't parse string."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _limit_buy_ioc() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::ImmediateOrCancelled, - price: Decimal::from_str("414.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.10000").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let resp = exchange - .limit_buy(&req) - .await - .expect("Couldn't request limit buy."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _limit_buy_fok() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::FillOrKill, - price: Decimal::from_str("414.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.10000").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let resp = exchange - .limit_buy(&req) - .await - .expect("Couldn't request limit buy."); - println!("{:?}", resp); -} - -#[tokio::test] -#[ignore] -async fn limit_buy_ggt() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillTime(Duration::hours(2)), - price: Decimal::from_str("414.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.02000").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let resp = exchange - .limit_buy(&req) - .await - .expect("Couldn't request limit buy."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _market_buy() { - let exchange = init().await; - let req = OpenMarketOrderRequest { - client_order_id: None, - size: Decimal::from_str("10.0").expect("Couldn't parse string."), - market_pair: String::from("usdc_eth"), - }; - let resp = exchange - .market_sell(&req) - .await - .expect("Couldn't request market buy."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _market_sell() { - let exchange = init().await; - let req = OpenMarketOrderRequest { - client_order_id: None, - size: Decimal::from_str("0.02").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - }; - let resp = exchange - .market_sell(&req) - .await - .expect("Couldn't request market buy."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _limit_sell() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillTime(Duration::hours(2)), - price: Decimal::from_str("800.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.02").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let resp = exchange - .limit_sell(&req) - .await - .expect("Couldn't request limit sell."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _cancel_order() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillCancelled, - price: Decimal::from_str("200.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.0300").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - let order = exchange - .limit_buy(&req) - .await - .expect("Couldn't request limit buy."); - - let req = CancelOrderRequest { - id: order.id, - market_pair: Some(order.market_pair), - }; - let resp = exchange - .cancel_order(&req) - .await - .expect("Couldn't cancel order."); - println!("{:?}", resp); -} - -// FIXME: https://github.com/nash-io/openlimits/issues/157 -// #[tokio::test] -async fn _cancel_all_orders() { - let exchange = init().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillCancelled, - price: Decimal::from_str("200.46").expect("Couldn't parse string."), - size: Decimal::from_str("0.10000").expect("Couldn't parse string."), - market_pair: String::from("eth_usdc"), - post_only: false, - }; - - exchange - .limit_sell(&req) - .await - .expect("Couldn't limit sell."); - - let req = CancelAllOrdersRequest { - market_pair: Some("eth_btc".to_string()), - }; - - let resp = exchange - .cancel_all_orders(&req) - .await - .expect("Couldn't cancel all orders."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_order_history() { - let exchange = init().await; - let req = GetOrderHistoryRequest { - market_pair: Some(String::from("eth_btc")), - order_status: None, - paginator: None, - }; - - let resp = exchange - .get_order_history(&req) - .await - .expect("Couldn't get order history."); - println!("{:?}", resp); -} - -// #[tokio::test] -// async fn get_all_open_orders() { -// let mut openlimits-exchange = init().await; -// let req = OpenLimitOrderRequest { -// client_order_id: None, -// time_in_force: TimeInForce::GoodTillCancelled, -// price: Decimal::new(1, 1), -// size: Decimal::new(2, 2), -// market_pair: String::from("eth_btc"), -// }; -// openlimits-exchange.limit_sell(&req).await.expect("Couldn't limit sell."); - -// let resp = openlimits-exchange.get_all_open_orders().await.expect("Couldn't get all open orders."); -// println!("{:?}", resp); -// } - -#[tokio::test] -async fn get_account_balances() { - let exchange = init().await; - let resp = exchange - .get_account_balances(None) - .await - .expect("Couldn't get account balances."); - println!("{:?}", resp); -} - -#[tokio::test] -async fn get_trade_history() { - let exchange = init().await; - let req = TradeHistoryRequest { - market_pair: Some("eth_btc".to_string()), - ..Default::default() - }; - - let resp = exchange - .get_trade_history(&req) - .await - .expect("Couldn't get trade history."); - println!("{:?}", resp); -} - -async fn init() -> Nash { - dotenv().ok(); - - let parameters = NashParameters { - affiliate_code: None, - credentials: Some(NashCredentials { - secret: env::var("NASH_API_SECRET").expect("Couldn't get environment variable."), - session: env::var("NASH_API_KEY").expect("Couldn't get environment variable."), - }), - environment: Environment::Sandbox, - client_id: 1, - timeout: NativeDuration::new(10, 0), - sign_states_loop_interval: None, - }; - - OpenLimits::instantiate(parameters) - .await - .expect("Failed to create Client") -} diff --git a/tests/old_nash_tests/market.rs b/tests/old_nash_tests/market.rs deleted file mode 100644 index 15484203..00000000 --- a/tests/old_nash_tests/market.rs +++ /dev/null @@ -1,110 +0,0 @@ -use nash_native_client::Environment; -use openlimits::{ - OpenLimits, - prelude::*, - model::GetHistoricTradesRequest, - model::Paginator, - model::{GetHistoricRatesRequest, GetPriceTickerRequest, Interval, OrderBookRequest}, - exchange::nash::Nash, - exchange::nash::NashCredentials, - exchange::nash::NashParameters, -}; - -use dotenv::dotenv; -use std::env; -use tokio::time::Duration; - -#[tokio::test] -async fn order_book() { - let exchange = init().await; - let req = OrderBookRequest { - market_pair: "eth_btc".to_string(), - }; - let _response = exchange - .order_book(&req) - .await - .expect("Couldn't get order book."); -} - -#[tokio::test] -async fn get_price_ticker() { - let exchange = init().await; - let req = GetPriceTickerRequest { - market_pair: "eth_btc".to_string(), - }; - let _response = exchange - .get_price_ticker(&req) - .await - .expect("Couldn't get price ticker."); -} - -#[tokio::test] -async fn get_historic_rates() { - let exchange = init().await; - let req = GetHistoricRatesRequest { - market_pair: "eth_btc".to_string(), - interval: Interval::OneHour, - paginator: None, - }; - let _response = exchange - .get_historic_rates(&req) - .await - .expect("Couldn't get historic rates."); -} - -#[tokio::test] -async fn get_historic_trades() { - let exchange = init().await; - let req = GetHistoricTradesRequest { - market_pair: "eth_btc".to_string(), - paginator: Some(Paginator { - limit: Some(100), - ..Default::default() - }), - }; - let _response = exchange - .get_historic_trades(&req) - .await - .expect("Couldn't get historic trades."); -} - -#[tokio::test] -async fn retrieve_pairs() { - let exchange = init().await; - let _response = exchange - .refresh_market_info() - .await - .expect("Couldn't get pairs."); -} - -// #[tokio::test] -// async fn get_historic_rates_invalid_interval() { -// let mut openlimits-exchange = init().await; -// let req = GetHistoricRatesRequest { -// market_pair: "eth_btc".to_string(), -// interval: Interval::TwoHours, -// paginator: None, -// }; -// let resp = openlimits-exchange.get_historic_rates(&req).await; -// assert!(resp.is_err()); -// } - -async fn init() -> Nash { - dotenv().ok(); - - let parameters = NashParameters { - affiliate_code: None, - credentials: Some(NashCredentials { - secret: env::var("NASH_API_SECRET").expect("Couldn't get environment variable."), - session: env::var("NASH_API_KEY").expect("Couldn't get environment variable."), - }), - environment: Environment::Sandbox, - client_id: 1, - timeout: Duration::new(10, 0), - sign_states_loop_interval: None, - }; - - OpenLimits::instantiate(parameters) - .await - .expect("Failed to create Client") -} diff --git a/tests/old_nash_tests/mod.rs b/tests/old_nash_tests/mod.rs deleted file mode 100644 index b66643a7..00000000 --- a/tests/old_nash_tests/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod account; -mod market; -mod websocket; diff --git a/tests/old_nash_tests/websocket.rs b/tests/old_nash_tests/websocket.rs deleted file mode 100644 index 2d3c0911..00000000 --- a/tests/old_nash_tests/websocket.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::{env, sync::mpsc::sync_channel}; -use std::str::FromStr; -use std::time::Duration as NativeDuration; - -use dotenv::dotenv; -use nash_native_client::Environment; -use rust_decimal::Decimal; -use tokio::time::Duration; - -use openlimits::{exchange::nash::NashWebsocket, model::websocket::Subscription}; -use openlimits::exchange::nash::{Nash, NashCredentials, NashParameters}; -use openlimits::exchange::traits::stream::{ExchangeWs, OpenLimitsWs}; -use openlimits::model::{CancelAllOrdersRequest, OpenLimitOrderRequest, TimeInForce}; -use openlimits::model::websocket::AccountOrders; -use openlimits::OpenLimits; -use openlimits::prelude::*; - -async fn init_exchange() -> Nash { - dotenv().ok(); - - let parameters = NashParameters { - affiliate_code: None, - credentials: Some(NashCredentials { - secret: env::var("NASH_API_SECRET").expect("Couldn't get environment variable."), - session: env::var("NASH_API_KEY").expect("Couldn't get environment variable."), - }), - environment: Environment::Sandbox, - client_id: 1, - timeout: NativeDuration::new(10, 0), - sign_states_loop_interval: None, - }; - - OpenLimits::instantiate(parameters) - .await - .expect("Failed to create Client") -} - -async fn test_subscription_callback(websocket: OpenLimitsWs, sub: Subscription) { - let (tx, rx) = sync_channel(0); - - websocket - .subscribe(sub, move |m| { - m.as_ref().expect("Couldn't get response."); - tx.send(()).expect("Couldn't send sync message."); - }) - .await - .expect("Couldn't subscribe."); - - rx.recv().expect("Couldn't receive sync message."); -} - -async fn test_account_subscription_callback( - websocket: OpenLimitsWs, - sub: Subscription, - cancel_orders: bool, -) { - let (tx, rx) = sync_channel(0); - - websocket - .subscribe(sub, move |m| { - m.as_ref().expect("Couldn't get response."); - tx.send(()).expect("Couldn't send sync message."); - }) - .await - .expect("Couldn't subscribe."); - - let exchange = init_exchange().await; - let req = OpenLimitOrderRequest { - client_order_id: None, - time_in_force: TimeInForce::GoodTillCancelled, - price: Decimal::from_str("0.01").expect("Couldn't parse string."), - size: Decimal::from_str("0.1").expect("Couldn't parse string."), - market_pair: String::from("eth_btc"), - post_only: false, - }; - - exchange - .limit_buy(&req) - .await - .expect("Couldn't limit sell."); - - if cancel_orders { - let req = CancelAllOrdersRequest { - market_pair: Some("eth_btc".to_string()), - }; - - let resp = exchange - .cancel_all_orders(&req) - .await - .expect("Couldn't cancel all orders."); - println!("{:?}", resp); - } - - rx.recv().expect("Couldn't receive sync message."); -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn account_orders() { - let client = init().await; - let sub = Subscription::AccountOrders(AccountOrders { - market: Some("eth_btc".to_string()), - order_type: None, - status: None, - buy_or_sell: None, - range: None, - }); - test_account_subscription_callback(client, sub, true).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn account_trades() { - let client = init().await; - let sub = Subscription::AccountTrades("eth_btc".to_string()); - test_account_subscription_callback(client, sub, false).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn account_balance() { - let client = init().await; - let sub = Subscription::AccountBalance("eth".to_string()); - test_account_subscription_callback(client, sub, false).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn orderbook() { - let client = init().await; - let sub = Subscription::OrderBookUpdates("btc_usdc".to_string()); - test_subscription_callback(client, sub).await; -} - -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn trades() { - let client = init().await; - let sub = Subscription::Trades("btc_usdc".to_string()); - test_subscription_callback(client, sub).await; -} - -async fn init() -> OpenLimitsWs { - dotenv().ok(); - - let websocket = NashWebsocket::new(NashParameters { - credentials: Some(NashCredentials { - secret: env::var("NASH_API_SECRET").expect("Couldn't get environment variable."), - session: env::var("NASH_API_KEY").expect("Couldn't get environment variable."), - }), - affiliate_code: None, - client_id: 1234, - environment: Environment::Sandbox, - timeout: Duration::from_secs(10), - sign_states_loop_interval: None, - }) - .await - .expect("Couldn't connect."); - - OpenLimitsWs { websocket } -} From ec375522ee0143cef1838c14b5163b779ad6e2fa Mon Sep 17 00:00:00 2001 From: Danilo Guanabara Date: Mon, 13 Dec 2021 09:54:07 -0300 Subject: [PATCH 2/4] String as input --- examples/csharp/Program.cs | 5 +++-- src/bindings/client.rs | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/csharp/Program.cs b/examples/csharp/Program.cs index cab4ab62..c0e48c89 100644 --- a/examples/csharp/Program.cs +++ b/examples/csharp/Program.cs @@ -11,8 +11,9 @@ class Program static public void Main(string[] args) { Console.WriteLine("String: " + Client.GetName()); - CoinbaseParameters parameters = new CoinbaseParameters(Environment.Production, "a", "b", "c"); - Client client = Client.Coinbase(parameters); + Console.WriteLine("Appended string: " + Client.AppendString("estringue")); +// CoinbaseParameters parameters = new CoinbaseParameters(Environment.Production, "a", "b", "c"); +// Client client = Client.Coinbase(parameters); // Console.WriteLine(Decimal.Parse(askBid.qty)); // Console.WriteLine(Decimal.Parse(askBid.qty)); // Console.WriteLine(askBid.price); diff --git a/src/bindings/client.rs b/src/bindings/client.rs index 71ff0c89..269c1ad3 100644 --- a/src/bindings/client.rs +++ b/src/bindings/client.rs @@ -44,6 +44,10 @@ impl Client { "Abc".into() } + pub fn append_string(s: String) -> String { + format!("hello {}", s) + } + // pub fn order_book(self, market_pair: String) -> OrderBookResponse { // unsafe { // let client = self.client.as_ref().unwrap(); From 4b3b9b13e4793a38b061d260d547b316c821e550 Mon Sep 17 00:00:00 2001 From: Danilo Guanabara Date: Tue, 14 Dec 2021 17:01:25 -0300 Subject: [PATCH 3/4] Reworking --- Cargo.toml | 7 +++-- build.rs | 10 +++++-- examples/csharp/Program.cs | 3 +- examples/csharp/run.sh | 4 +-- src/bindings/ask_bid.rs | 2 +- src/bindings/client.rs | 50 ++++++++++++++++++--------------- src/bindings/client/coinbase.rs | 30 +++++++++++--------- src/bindings/mod.rs | 6 ++-- src/bindings/orderbook.rs | 2 +- src/bindings/string/mod.rs | 2 +- src/bindings/vector/mod.rs | 2 +- 11 files changed, 67 insertions(+), 51 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 537a2313..5fefef6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ path = "examples/rust/orderbook.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -bindings = ["ligen", "ligen-macro", "ligen-csharp"] +bindings = ["ligen", "ligen-macro", "ligen-cargo", "ligen-rust", "ligen-csharp"] default = ["rust_gmp"] rust_gmp = ["openlimits-nash/rust_gmp"] num_bigint = ["openlimits-nash/num_bigint"] @@ -38,4 +38,7 @@ dotenv = "0.15.0" [build-dependencies] ligen = { path = "../../sensorial/systems/ligen/ligen", optional = true } -ligen-csharp = { path = "../../sensorial/systems/ligen/generators/ligen-csharp", optional = true } \ No newline at end of file +ligen-cargo = { path = "../../sensorial/systems/ligen/generators/ligen-cargo", optional = true } +ligen-rust = { path = "../../sensorial/systems/ligen/generators/ligen-rust", optional = true } +ligen-csharp = { path = "../../sensorial/systems/ligen/generators/ligen-csharp", optional = true } +serde_json = "1.0.73" \ No newline at end of file diff --git a/build.rs b/build.rs index 1bb8cdfe..c0a0f2eb 100644 --- a/build.rs +++ b/build.rs @@ -4,14 +4,18 @@ fn main() { { use ligen::prelude::*; use ligen_csharp::CSharpGenerator; + use ligen_cargo::CargoProject; + use ligen_rust::RustGenerator; - match Project::current() { + match CargoProject::current().and_then(Project::try_from) { Ok(project) => { println!("Generating C# bindings..."); + let rust_generator = RustGenerator::default(); let csharp_generator = CSharpGenerator::default(); - csharp_generator.generate(&project).expect("Failed to generate C# bindings."); + rust_generator.generate(&project).expect("Failed to generate Rust interface."); + csharp_generator.generate(&project).expect("Failed to generate C# interface."); }, - Err(e) => println!("e: {:#?}", e) + Err(e) => panic!("e: {:#?}", e) } } } diff --git a/examples/csharp/Program.cs b/examples/csharp/Program.cs index c0e48c89..b4c1dabd 100644 --- a/examples/csharp/Program.cs +++ b/examples/csharp/Program.cs @@ -10,9 +10,10 @@ class Program { static public void Main(string[] args) { + CoinbaseParameters parameters = new CoinbaseParameters(Environment.Production, "a", "b", "c"); Console.WriteLine("String: " + Client.GetName()); Console.WriteLine("Appended string: " + Client.AppendString("estringue")); -// CoinbaseParameters parameters = new CoinbaseParameters(Environment.Production, "a", "b", "c"); + Console.WriteLine("Appended strings in structure: " + Client.AppendParameters(parameters)); // Client client = Client.Coinbase(parameters); // Console.WriteLine(Decimal.Parse(askBid.qty)); // Console.WriteLine(Decimal.Parse(askBid.qty)); diff --git a/examples/csharp/run.sh b/examples/csharp/run.sh index 6679eaa2..4002ef13 100755 --- a/examples/csharp/run.sh +++ b/examples/csharp/run.sh @@ -1,5 +1,5 @@ # cargo build --manifest-path ../../Cargo.toml -cp ../../target/ligen/ffi/openlimits/target/release/ffi_openlimits.dll ./bin/Debug/netcoreapp5.0/ffi_openlimits.dll -# cp ../../target/ligen/openlimits/lib/libopenlimits.so ./bin/Debug/netcoreapp5.0/libopenlimits_csharp.so +#cp ../../target/ligen/ffi/openlimits/target/release/ffi_openlimits.dll ./bin/Debug/netcoreapp5.0/ffi_openlimits.dll +cp ../../target/ligen/ffi/openlimits/target/release/libffi_openlimits.so ./bin/Debug/netcoreapp5.0/libffi_openlimits.so dotnet run diff --git a/src/bindings/ask_bid.rs b/src/bindings/ask_bid.rs index e0391973..b9a43e8e 100644 --- a/src/bindings/ask_bid.rs +++ b/src/bindings/ask_bid.rs @@ -1,4 +1,4 @@ -use ligen::marshalling::{MarshalFrom, MarshalInto}; +use ligen::traits::marshalling::{MarshalFrom, MarshalInto}; use crate::model::AskBid; use rust_decimal::Decimal; use std::str::FromStr; diff --git a/src/bindings/client.rs b/src/bindings/client.rs index 269c1ad3..44514313 100644 --- a/src/bindings/client.rs +++ b/src/bindings/client.rs @@ -5,6 +5,7 @@ use openlimits_coinbase::{Coinbase, CoinbaseParameters}; pub mod coinbase; + mod runtime { use ligen_macro::inner_ligen; @@ -24,29 +25,34 @@ pub struct Client { } impl Client { - pub fn coinbase(parameters: CoinbaseParameters) -> Self { - let client = crate::OpenLimits::instantiate(parameters); - let client = RUNTIME.block_on(client); - let client = client.unwrap(); - let client = Box::into_raw(Box::new(client)); - Self { client } - } - - pub fn sum(self, a: Vec) -> u64 { - a.iter().sum() - } - - pub fn mul(self, a: Vec, n: u64) -> Vec { - a.iter().map(|x| x * n).collect() - } - - pub fn get_name() -> String { - "Abc".into() - } + // pub fn coinbase(parameters: CoinbaseParameters) -> Self { + // let client = crate::OpenLimits::instantiate(parameters); + // let client = RUNTIME.block_on(client); + // let client = client.unwrap(); + // let client = Box::into_raw(Box::new(client)); + // Self { client } + // } - pub fn append_string(s: String) -> String { - format!("hello {}", s) - } + // pub fn sum(self, a: Vec) -> u64 { + // a.iter().sum() + // } + // + // pub fn mul(self, a: Vec, n: u64) -> Vec { + // a.iter().map(|x| x * n).collect() + // } + // + // pub fn get_name() -> String { + // "Abc".into() + // } + // + // pub fn append_string(s: String) -> String { + // format!("hello {}", s) + // } + // + // pub fn append_parameters(p: CoinbaseParameters) -> String { + // let credentials = p.credentials.unwrap(); + // format!("{}{}{}", credentials.api_key, credentials.api_secret, credentials.passphrase) + // } // pub fn order_book(self, market_pair: String) -> OrderBookResponse { // unsafe { diff --git a/src/bindings/client/coinbase.rs b/src/bindings/client/coinbase.rs index 0ef70485..1e459b78 100644 --- a/src/bindings/client/coinbase.rs +++ b/src/bindings/client/coinbase.rs @@ -1,7 +1,7 @@ use crate::bindings::string::FFIString; use crate::bindings::environment::Environment; use openlimits_coinbase::{CoinbaseParameters, CoinbaseCredentials}; -use ligen::marshalling::MarshalFrom; +use ligen::traits::marshalling::MarshalFrom; use ligen_macro::inner_ligen; inner_ligen! { @@ -23,22 +23,24 @@ inner_ligen! { #[repr(C, packed(1))] pub struct FFICoinbaseParameters { environment: Environment, - apiKey: FFIString, - apiSecret: FFIString, - passphrase: FFIString + apiKey: *mut FFIString, + apiSecret: *mut FFIString, + passphrase: *mut FFIString } impl MarshalFrom for CoinbaseParameters { fn marshal_from(from: FFICoinbaseParameters) -> Self { - let api_key = String::marshal_from(from.apiKey); - let api_secret = String::marshal_from(from.apiSecret); - let passphrase = String::marshal_from(from.passphrase); - let credentials = if !api_key.is_empty() && !api_secret.is_empty() && !passphrase.is_empty() { - Some(CoinbaseCredentials { api_key, api_secret, passphrase }) - } else { - None - }; - let environment = from.environment.into(); - Self { environment, credentials } + unsafe { + let api_key = String::marshal_from(from.apiKey.read()); + let api_secret = String::marshal_from(from.apiSecret.read()); + let passphrase = String::marshal_from(from.passphrase.read()); + let credentials = if !api_key.is_empty() && !api_secret.is_empty() && !passphrase.is_empty() { + Some(CoinbaseCredentials { api_key, api_secret, passphrase }) + } else { + None + }; + let environment = from.environment.into(); + Self { environment, credentials } + } } } \ No newline at end of file diff --git a/src/bindings/mod.rs b/src/bindings/mod.rs index a57ddb39..be57d2c2 100644 --- a/src/bindings/mod.rs +++ b/src/bindings/mod.rs @@ -3,9 +3,9 @@ pub mod string; pub mod environment; pub mod client; -pub mod ask_bid; -pub mod orderbook; -pub mod vector; +// pub mod ask_bid; +// pub mod orderbook; +// pub mod vector; // use ligen::marshalling::{MarshalFrom, MarshalInto}; // #[repr(C)] diff --git a/src/bindings/orderbook.rs b/src/bindings/orderbook.rs index ff3e2486..6c05f312 100644 --- a/src/bindings/orderbook.rs +++ b/src/bindings/orderbook.rs @@ -2,7 +2,7 @@ use crate::model::OrderBookResponse; use crate::bindings::vector::FFIVector; use ligen_macro::inner_ligen; use std::ptr::null_mut; -use ligen::marshalling::MarshalFrom; +use ligen::traits::marshalling::MarshalFrom; use crate::bindings::ask_bid::FFIAskBid; // # Replicate generics logic to struct fields. diff --git a/src/bindings/string/mod.rs b/src/bindings/string/mod.rs index 6a3f51b8..a575cf21 100644 --- a/src/bindings/string/mod.rs +++ b/src/bindings/string/mod.rs @@ -1,4 +1,4 @@ -use ligen::marshalling::{MarshalFrom, MarshalInto}; +use ligen::traits::marshalling::{MarshalFrom, MarshalInto}; use ligen_macro::inner_ligen; use rust_decimal::Decimal; use std::ffi::{CString, CStr}; diff --git a/src/bindings/vector/mod.rs b/src/bindings/vector/mod.rs index 5450cdc7..823c40cd 100644 --- a/src/bindings/vector/mod.rs +++ b/src/bindings/vector/mod.rs @@ -1,5 +1,5 @@ use ligen_macro::inner_ligen; -use ligen::marshalling::MarshalFrom; +use ligen::traits::marshalling::MarshalFrom; use std::ptr::null_mut; inner_ligen! { From cc98e525f7fb5cbe349aaa53db261f8e4893d48f Mon Sep 17 00:00:00 2001 From: Danilo Guanabara Date: Wed, 15 Dec 2021 21:04:49 -0300 Subject: [PATCH 4/4] WIP Rust exporter --- TODO | 1 + build.rs | 10 ++- examples/csharp/run.sh | 4 +- examples/test/Program.cs | 29 ++++++++ examples/test/bin/Debug/net5.0/ref/test.dll | Bin 0 -> 5632 bytes examples/test/bin/Debug/net5.0/test.deps.json | 23 ++++++ examples/test/bin/Debug/net5.0/test.dll | Bin 0 -> 5632 bytes examples/test/bin/Debug/net5.0/test.exe | Bin 0 -> 127488 bytes examples/test/bin/Debug/net5.0/test.pdb | Bin 0 -> 10036 bytes .../Debug/net5.0/test.runtimeconfig.dev.json | 8 +++ .../bin/Debug/net5.0/test.runtimeconfig.json | 9 +++ ...CoreApp,Version=v5.0.AssemblyAttributes.cs | 4 ++ examples/test/obj/Debug/net5.0/apphost.exe | Bin 0 -> 127488 bytes examples/test/obj/Debug/net5.0/ref/test.dll | Bin 0 -> 5632 bytes .../obj/Debug/net5.0/test.AssemblyInfo.cs | 22 ++++++ .../net5.0/test.AssemblyInfoInputs.cache | 1 + ....GeneratedMSBuildEditorConfig.editorconfig | 8 +++ .../test/obj/Debug/net5.0/test.assets.cache | Bin 0 -> 140 bytes .../test.csproj.AssemblyReference.cache | Bin 0 -> 69896 bytes .../test.csproj.CoreCompileInputs.cache | 1 + .../net5.0/test.csproj.FileListAbsolute.txt | 16 +++++ examples/test/obj/Debug/net5.0/test.dll | Bin 0 -> 5632 bytes .../Debug/net5.0/test.genruntimeconfig.cache | 1 + examples/test/obj/Debug/net5.0/test.pdb | Bin 0 -> 10036 bytes examples/test/obj/project.assets.json | 67 +++++++++++++++++ examples/test/obj/project.nuget.cache | 8 +++ .../test/obj/test.csproj.nuget.dgspec.json | 62 ++++++++++++++++ examples/test/obj/test.csproj.nuget.g.props | 18 +++++ examples/test/obj/test.csproj.nuget.g.targets | 6 ++ examples/test/test.csproj | 8 +++ src/bindings/client.rs | 9 ++- src/bindings/client/coinbase.rs | 46 ------------ src/bindings/mod.rs | 1 - src/bindings/string/mod.rs | 68 ------------------ src/bindings/string/string.methods.cs | 17 ----- src/bindings/vector/mod.rs | 54 -------------- src/bindings/vector/vector.methods.cs | 24 ------- 37 files changed, 305 insertions(+), 220 deletions(-) create mode 100644 TODO create mode 100644 examples/test/Program.cs create mode 100644 examples/test/bin/Debug/net5.0/ref/test.dll create mode 100644 examples/test/bin/Debug/net5.0/test.deps.json create mode 100644 examples/test/bin/Debug/net5.0/test.dll create mode 100644 examples/test/bin/Debug/net5.0/test.exe create mode 100644 examples/test/bin/Debug/net5.0/test.pdb create mode 100644 examples/test/bin/Debug/net5.0/test.runtimeconfig.dev.json create mode 100644 examples/test/bin/Debug/net5.0/test.runtimeconfig.json create mode 100644 examples/test/obj/Debug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs create mode 100644 examples/test/obj/Debug/net5.0/apphost.exe create mode 100644 examples/test/obj/Debug/net5.0/ref/test.dll create mode 100644 examples/test/obj/Debug/net5.0/test.AssemblyInfo.cs create mode 100644 examples/test/obj/Debug/net5.0/test.AssemblyInfoInputs.cache create mode 100644 examples/test/obj/Debug/net5.0/test.GeneratedMSBuildEditorConfig.editorconfig create mode 100644 examples/test/obj/Debug/net5.0/test.assets.cache create mode 100644 examples/test/obj/Debug/net5.0/test.csproj.AssemblyReference.cache create mode 100644 examples/test/obj/Debug/net5.0/test.csproj.CoreCompileInputs.cache create mode 100644 examples/test/obj/Debug/net5.0/test.csproj.FileListAbsolute.txt create mode 100644 examples/test/obj/Debug/net5.0/test.dll create mode 100644 examples/test/obj/Debug/net5.0/test.genruntimeconfig.cache create mode 100644 examples/test/obj/Debug/net5.0/test.pdb create mode 100644 examples/test/obj/project.assets.json create mode 100644 examples/test/obj/project.nuget.cache create mode 100644 examples/test/obj/test.csproj.nuget.dgspec.json create mode 100644 examples/test/obj/test.csproj.nuget.g.props create mode 100644 examples/test/obj/test.csproj.nuget.g.targets create mode 100644 examples/test/test.csproj delete mode 100644 src/bindings/client/coinbase.rs delete mode 100644 src/bindings/string/mod.rs delete mode 100644 src/bindings/string/string.methods.cs delete mode 100644 src/bindings/vector/mod.rs delete mode 100644 src/bindings/vector/vector.methods.cs diff --git a/TODO b/TODO new file mode 100644 index 00000000..1e2079b6 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +Fix hardcoded values in CargoBuilde diff --git a/build.rs b/build.rs index c0a0f2eb..834e516f 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,10 @@ - fn main() { #[cfg(feature = "bindings")] { use ligen::prelude::*; + use ligen::traits::build::{BuildSystem, BuildProfile}; use ligen_csharp::CSharpGenerator; - use ligen_cargo::CargoProject; + use ligen_cargo::{CargoProject, CargoGenerator, CargoBuilder}; use ligen_rust::RustGenerator; match CargoProject::current().and_then(Project::try_from) { @@ -12,10 +12,14 @@ fn main() { println!("Generating C# bindings..."); let rust_generator = RustGenerator::default(); let csharp_generator = CSharpGenerator::default(); + let cargo_generator = CargoGenerator::default(); + let cargo_builder = CargoBuilder; + cargo_generator.generate(&project).expect("Failed to generate Cargo interface."); rust_generator.generate(&project).expect("Failed to generate Rust interface."); csharp_generator.generate(&project).expect("Failed to generate C# interface."); + cargo_builder.build(&project, BuildProfile::Release).expect("Failed to build Cargo project."); }, - Err(e) => panic!("e: {:#?}", e) + Err(_) => () } } } diff --git a/examples/csharp/run.sh b/examples/csharp/run.sh index 4002ef13..0df9004a 100755 --- a/examples/csharp/run.sh +++ b/examples/csharp/run.sh @@ -1,5 +1,5 @@ # cargo build --manifest-path ../../Cargo.toml -#cp ../../target/ligen/ffi/openlimits/target/release/ffi_openlimits.dll ./bin/Debug/netcoreapp5.0/ffi_openlimits.dll -cp ../../target/ligen/ffi/openlimits/target/release/libffi_openlimits.so ./bin/Debug/netcoreapp5.0/libffi_openlimits.so +cp ../../target/ligen/ffi/openlimits/target/release/ffi_openlimits.dll ./bin/Debug/netcoreapp5.0/ffi_openlimits.dll +#cp ../../target/ligen/ffi/openlimits/target/release/libffi_openlimits.so ./bin/Debug/netcoreapp5.0/libffi_openlimits.so dotnet run diff --git a/examples/test/Program.cs b/examples/test/Program.cs new file mode 100644 index 00000000..ca592092 --- /dev/null +++ b/examples/test/Program.cs @@ -0,0 +1,29 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace test { + class Account { + public decimal quantity { get; set; } + } + + class Person { + public string name { get; set; } + public int age { get; set; } + public Account account { get; set; } + } + + class Program { + static void Main(string[] args) { + var person = new Person(); + person.name = "Danilo"; + person.age = 33; + person.account = new Account(); + person.account.quantity = 12314; + string json = JsonSerializer.Serialize(person); + Console.WriteLine(json); + Person fromJson = JsonSerializer.Deserialize(json); + Console.WriteLine(fromJson.account.quantity); + } + } +} diff --git a/examples/test/bin/Debug/net5.0/ref/test.dll b/examples/test/bin/Debug/net5.0/ref/test.dll new file mode 100644 index 0000000000000000000000000000000000000000..2e0fc0078b21da370379165bdba8f2fce3ba446a GIT binary patch literal 5632 zcmeHLO>7)h60UBKo$+L2>?A~iMbM1d#r&jg;{-zRB;)uGLt=a5iP7#Jk~ckX#tr>5 z>Fyak9KcBYoRGL6Ax=5)cR+#z5)nTlDfBmJoOM!2J_-YqH|bz6czmcU<2ZTo8BFuxBEZ2`J8s_lbcIx zc4*WCzZMABu!QINkx`aL(C`e~GiH`n4A-wnbH|R{Es5#nS)yZFhCY9_@?pB$1%vHPi77WDlofz@=Ib_FZEYsZrM%`6^8qN8Rc*CXK0wwR%E z(g(b281UWkMFajUr5%fpmN*a!j;=i5${y%&t+yzFp*1^a{?v+1EeY zRsQ17)35v^X#DG$7x1OKI(|vF@7%_>?H^AW7M7D$B7Q2`P3O-i2~cJg{<*9>M)n^;gc)$25_#C!}BK> zX0W~w`fH|-I(``|4?M2TUwc;TXX1a_1nr6azXl}R*`BQI%PvglD?Yaujx&z+O)Xyg z=zIFF)doN%oy)C<* zZtJ3kVXY&}(LQv>)XGlS=ur3Q$e-s7VTwm1$47F+(9MtuT_Vd7|M(Hu%%NTelq<%u7!OB9fJ<2;Zl2Ba$>D%Z*x1 zlpWdOO@*O!%TB9gN8Rj_2(Z%}E^qQtKX_!T{v7sLl|g9x-d5p)SM>u|L=Xz+C$*-1 zuWHvCaB`E8H~_^wAsw-yHmhf~y0Q;Ow6go@of2 zlBlJQQ=5nn-Io5JF*GgPW02MhWN3)Vf$UpHPCYU7Meb0>prL{i6reJInFVWSmRUQq znGr~PM!+8de+2xjrtYgmH*$?D>3bduM19fsX4frQ=hT$e0{_uagWfi-fs|o*K%>3p z;%sT!59Cz6erJ;VLi2z*1}g)*+b49!4(pC+E%H~RU!#l)nR56_s#A|^E)0*O`{0A0 z65uN$4!sT49lT8uO(s2&S*wf}8QVJ2-Wf|y!QI()d0f~YxuFH$r8*rfz4#|87Gt&F zG}KkEHHbF$!p~)_o865&)xpc~S?>~MaAN(nEh6=QGI_i~4?GtEk3qA7Kq)na5p9H}!HxNi4NzeUne!&y3;ArnUW9#WMlyb^ISkPaJDc-h;ao zXMn8)SOsG4c$C^UsRBOV+VJ}l-A$uo(61?Nj;2m6p*?`-iMP%)?LSF#_h0>M`g(yXhePmg}RVGS(@8-FmHsB@G8Rb zJz2=NWSBp4ct>tWZc-!-*nkNyEaV%3cPO;hq$|RGu5AT==vSkCmhT=Cp=&nB^M)%t zyNZgQ7DKfkj2TAT*g{3BI={&$E`51}?+k_f@fOOdV_T}ZnxbCMkH!|FpbK6CFXK(>`sgO#Cr8^!fWqWx`i2hUM5 P?Vc++$g8paR0e(op4QI7 literal 0 HcmV?d00001 diff --git a/examples/test/bin/Debug/net5.0/test.deps.json b/examples/test/bin/Debug/net5.0/test.deps.json new file mode 100644 index 00000000..cd012c3f --- /dev/null +++ b/examples/test/bin/Debug/net5.0/test.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "test/1.0.0": { + "runtime": { + "test.dll": {} + } + } + } + }, + "libraries": { + "test/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/examples/test/bin/Debug/net5.0/test.dll b/examples/test/bin/Debug/net5.0/test.dll new file mode 100644 index 0000000000000000000000000000000000000000..373ba3a3dc63ba6a7c8195cbd08c479da74e5e7b GIT binary patch literal 5632 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 literal 0 HcmV?d00001 diff --git a/examples/test/bin/Debug/net5.0/test.exe b/examples/test/bin/Debug/net5.0/test.exe new file mode 100644 index 0000000000000000000000000000000000000000..8d88523f87bbb99092f26f35aff7563ab470e1d8 GIT binary patch literal 127488 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
FIOpT6POJQ3)7_R=EBut`F;m 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 GT>lpYh`faW literal 0 HcmV?d00001 diff --git a/examples/test/bin/Debug/net5.0/test.pdb b/examples/test/bin/Debug/net5.0/test.pdb new file mode 100644 index 0000000000000000000000000000000000000000..1ab5f31a0c1026df5a0b61c8f112c3d655267fd2 GIT binary patch literal 10036 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 +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")] diff --git a/examples/test/obj/Debug/net5.0/apphost.exe b/examples/test/obj/Debug/net5.0/apphost.exe new file mode 100644 index 0000000000000000000000000000000000000000..8d88523f87bbb99092f26f35aff7563ab470e1d8 GIT binary patch literal 127488 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
FIOpT6POJQ3)7_R=EBut`F;m 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 GT>lpYh`faW literal 0 HcmV?d00001 diff --git a/examples/test/obj/Debug/net5.0/ref/test.dll b/examples/test/obj/Debug/net5.0/ref/test.dll new file mode 100644 index 0000000000000000000000000000000000000000..2e0fc0078b21da370379165bdba8f2fce3ba446a GIT binary patch literal 5632 zcmeHLO>7)h60UBKo$+L2>?A~iMbM1d#r&jg;{-zRB;)uGLt=a5iP7#Jk~ckX#tr>5 z>Fyak9KcBYoRGL6Ax=5)cR+#z5)nTlDfBmJoOM!2J_-YqH|bz6czmcU<2ZTo8BFuxBEZ2`J8s_lbcIx zc4*WCzZMABu!QINkx`aL(C`e~GiH`n4A-wnbH|R{Es5#nS)yZFhCY9_@?pB$1%vHPi77WDlofz@=Ib_FZEYsZrM%`6^8qN8Rc*CXK0wwR%E z(g(b281UWkMFajUr5%fpmN*a!j;=i5${y%&t+yzFp*1^a{?v+1EeY zRsQ17)35v^X#DG$7x1OKI(|vF@7%_>?H^AW7M7D$B7Q2`P3O-i2~cJg{<*9>M)n^;gc)$25_#C!}BK> zX0W~w`fH|-I(``|4?M2TUwc;TXX1a_1nr6azXl}R*`BQI%PvglD?Yaujx&z+O)Xyg z=zIFF)doN%oy)C<* zZtJ3kVXY&}(LQv>)XGlS=ur3Q$e-s7VTwm1$47F+(9MtuT_Vd7|M(Hu%%NTelq<%u7!OB9fJ<2;Zl2Ba$>D%Z*x1 zlpWdOO@*O!%TB9gN8Rj_2(Z%}E^qQtKX_!T{v7sLl|g9x-d5p)SM>u|L=Xz+C$*-1 zuWHvCaB`E8H~_^wAsw-yHmhf~y0Q;Ow6go@of2 zlBlJQQ=5nn-Io5JF*GgPW02MhWN3)Vf$UpHPCYU7Meb0>prL{i6reJInFVWSmRUQq znGr~PM!+8de+2xjrtYgmH*$?D>3bduM19fsX4frQ=hT$e0{_uagWfi-fs|o*K%>3p z;%sT!59Cz6erJ;VLi2z*1}g)*+b49!4(pC+E%H~RU!#l)nR56_s#A|^E)0*O`{0A0 z65uN$4!sT49lT8uO(s2&S*wf}8QVJ2-Wf|y!QI()d0f~YxuFH$r8*rfz4#|87Gt&F zG}KkEHHbF$!p~)_o865&)xpc~S?>~MaAN(nEh6=QGI_i~4?GtEk3qA7Kq)na5p9H}!HxNi4NzeUne!&y3;ArnUW9#WMlyb^ISkPaJDc-h;ao zXMn8)SOsG4c$C^UsRBOV+VJ}l-A$uo(61?Nj;2m6p*?`-iMP%)?LSF#_h0>M`g(yXhePmg}RVGS(@8-FmHsB@G8Rb zJz2=NWSBp4ct>tWZc-!-*nkNyEaV%3cPO;hq$|RGu5AT==vSkCmhT=Cp=&nB^M)%t zyNZgQ7DKfkj2TAT*g{3BI={&$E`51}?+k_f@fOOdV_T}ZnxbCMkH!|FpbK6CFXK(>`sgO#Cr8^!fWqWx`i2hUM5 P?Vc++$g8paR0e(op4QI7 literal 0 HcmV?d00001 diff --git a/examples/test/obj/Debug/net5.0/test.AssemblyInfo.cs b/examples/test/obj/Debug/net5.0/test.AssemblyInfo.cs new file mode 100644 index 00000000..e84e9e5c --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.AssemblyInfo.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("test")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("test")] +[assembly: System.Reflection.AssemblyTitleAttribute("test")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/examples/test/obj/Debug/net5.0/test.AssemblyInfoInputs.cache b/examples/test/obj/Debug/net5.0/test.AssemblyInfoInputs.cache new file mode 100644 index 00000000..85928a81 --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +a987eb0675210088860249537ec979b0010c987d diff --git a/examples/test/obj/Debug/net5.0/test.GeneratedMSBuildEditorConfig.editorconfig b/examples/test/obj/Debug/net5.0/test.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 00000000..d7e29835 --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,8 @@ +is_global = true +build_property.TargetFramework = net5.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.PublishSingleFile = +build_property.IncludeAllContentForSelfExtract = +build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows diff --git a/examples/test/obj/Debug/net5.0/test.assets.cache b/examples/test/obj/Debug/net5.0/test.assets.cache new file mode 100644 index 0000000000000000000000000000000000000000..bca05336bae7856fe6ac1d1a41354f536c00440a GIT binary patch literal 140 zcmWIWc6a1rU|_g?Q((rbXZJHtzw^=jz3`RV6A?dU-`vGUwm)ty?z-%>v;(My5MTr< nkaxC<2`x@7Dvn7>%u6qg(aS4MPc4ZlNKDR7OiwM2!Dj{lCn_Jz literal 0 HcmV?d00001 diff --git a/examples/test/obj/Debug/net5.0/test.csproj.AssemblyReference.cache b/examples/test/obj/Debug/net5.0/test.csproj.AssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..e97c9ee60b6cc4b8006abff09b9bb33ed5538a87 GIT binary patch literal 69896 zcmd^|4Uingb%1w;{wxKA{$d%BkO+`~r1dSUJN;Q!NvE@Ol7b+=s1u%siOksWs8HgPxC{&1r z)3ZBoUe9dL-gw2vtahyiT0N6X44{xRr!3Pll1pCCK?hAy%znBO4ENZ zqRm}{nw3vvve|f?{*GAZvhRM{esN+v9={wvuPhWF=Lj%gr2_Qd@xAWhHh$XIuLgJWdwOe*c9P_EvM@8^8J7wr@>2 zxqrp=SN+AbW-@DT?)Za?+HQUJ!T3a4r*E&^zIW zU~Y3UYZooD!XQQ4(y|NYb`<-vdirKE(rpeAV?|#>s=u*+aep$IX>8C^8vT6w6`!cZ@<&{Yz{+e9;5UF`3tlRpCd(!L+MW_g*blq({V-pyY)d3sOxUoSfL-7A*QioLr0 zgQNfW&eE7Yc4pI~ubn=-cl+3%O!@q-jgRfS@9`VnzA*JCKRCSn(aSz~^oeg=lim5H z#gkf}yX3tY>xPVfzGlnkA6c??j&Xk1nSFn!eIoWx?~@m<`td8L-}tX|!>NN;uex*N zLs$O#+A}wN^hal>zxME|)Uw&*&i?S(`Abfh9HKLyp8mUkS@`o?;hDiyZpvgbjY)U<@wr1gMWbsrvsse1soz$hzL1eFS{5<5ra0SGkY7S1*!uExcU0B8 z2F_93UR@^V^|@Tp*7~vp4HoCot2pX<1=OXyy_(vRAWJpocGFl(3}VqWj^_j8N|k5K zSVCRQJYz<^C2<~-Y0O=DlGe4Xemlt^Xk6^f;q+^!h`OY;>WWK3yr-) zx=1%xDk}-2As%BcZyMCIYBMt=n^K+Xtu`X zKK^&d+{My$eBA>j<1`@b`}zYSRY!mOz?)t6iqG4s@v z3tR4c{%4J^w=Vr+OY?+tuPwjp`WY*ZoI1b%PV>Ms@2%~4<3Mlb)maaQ*PmL_*ra7rO^ZmXk+-yx z&A(+gHGdj(CYe=*5rgr{jC)R2=N~AkuI-2L59p8lg+{h=lI_2G_;N14>ti8xsi#L% zT@vuTWZ>N+c|t=fyNP8J3w`tB%MZBb{wI9JedW}}-XB4GN#wMI7iiKi~YjO>R+34IFRouFfI!Q=-! zVRyn6QP&({cfwT^(Ft{-HjB4Inv&yNEZQtiC~;*KfPq@B!mH~V_M(Ql%0r%yYq-*q@QPmtcw=}W(Ph&! zD&5o{V@7hEt-W;sw}iToy>$s!Z%LeoWsct6H1~OvrPED<66{u;=0(%QEgZ#h$KXaz z4-YA>ZV$*sZv;u*L8^b=ZJJqTOh=37`R65Jby4&D^ODMvzzWaQV?E81bq8H@#0!~v zAw|@M44HZ%ic3N*)iZNY>jrm~&GXD$adi>%JTq5mNqGB(&)AkW>>$OA44k0Rh(88% zQ-!p;aC<{_mc&;04&fS?mKP|-bu;V`x*}0y#Rr|uA9{d$>>U@&fo|9#bQMK((F6Pu zj&rAlo8^e1<>(oQ&Z1%KIcBAV2>%%Rr(aZEgWSSb7?BDMR__pv^i!sl)94<=s)CWk zF&2*$PIuK~IN81`mMu|}h_kP!A%|7R7N;!?DS<4b5qp{~iapDB;H>8M2 zzV#KG1n)OQ@fuJ^iA!ch8?C?kye(|pNxa(a(qU!Ph21xb=8|X&&yVwy^V}v3R6%~6 zPf%U1kRRt$R}xI&835}yI0-~~i*6;*q?5#I%e1pPPP}-Q5HbL`1){_MyKD8#ub-AEAMT@00`-xK+

?19>Qy%k+GNM-j+ifczm9ru5}r1lf; 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 literal 0 HcmV?d00001 diff --git a/examples/test/obj/Debug/net5.0/test.csproj.CoreCompileInputs.cache b/examples/test/obj/Debug/net5.0/test.csproj.CoreCompileInputs.cache new file mode 100644 index 00000000..d9a3bb41 --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +d9bf6df19d9e130c226f3887e01298d8b37e12eb diff --git a/examples/test/obj/Debug/net5.0/test.csproj.FileListAbsolute.txt b/examples/test/obj/Debug/net5.0/test.csproj.FileListAbsolute.txt new file mode 100644 index 00000000..9d6eb78e --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.csproj.FileListAbsolute.txt @@ -0,0 +1,16 @@ +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.exe +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.deps.json +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.runtimeconfig.json +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.runtimeconfig.dev.json +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.dll +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\ref\test.dll +C:\Users\dangu\dev\nash-io\openlimits\examples\test\bin\Debug\net5.0\test.pdb +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.csproj.AssemblyReference.cache +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.GeneratedMSBuildEditorConfig.editorconfig +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.AssemblyInfoInputs.cache +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.AssemblyInfo.cs +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.csproj.CoreCompileInputs.cache +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.dll +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\ref\test.dll +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.pdb +C:\Users\dangu\dev\nash-io\openlimits\examples\test\obj\Debug\net5.0\test.genruntimeconfig.cache diff --git a/examples/test/obj/Debug/net5.0/test.dll b/examples/test/obj/Debug/net5.0/test.dll new file mode 100644 index 0000000000000000000000000000000000000000..373ba3a3dc63ba6a7c8195cbd08c479da74e5e7b GIT binary patch literal 5632 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 literal 0 HcmV?d00001 diff --git a/examples/test/obj/Debug/net5.0/test.genruntimeconfig.cache b/examples/test/obj/Debug/net5.0/test.genruntimeconfig.cache new file mode 100644 index 00000000..6fe3366c --- /dev/null +++ b/examples/test/obj/Debug/net5.0/test.genruntimeconfig.cache @@ -0,0 +1 @@ +9431f34b09501de181957879814907a9286e0a25 diff --git a/examples/test/obj/Debug/net5.0/test.pdb b/examples/test/obj/Debug/net5.0/test.pdb new file mode 100644 index 0000000000000000000000000000000000000000..1ab5f31a0c1026df5a0b61c8f112c3d655267fd2 GIT binary patch literal 10036 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 + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\dangu\.nuget\packages\ + PackageReference + 5.10.0 + + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + \ No newline at end of file diff --git a/examples/test/obj/test.csproj.nuget.g.targets b/examples/test/obj/test.csproj.nuget.g.targets new file mode 100644 index 00000000..53cfaa19 --- /dev/null +++ b/examples/test/obj/test.csproj.nuget.g.targets @@ -0,0 +1,6 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + \ No newline at end of file diff --git a/examples/test/test.csproj b/examples/test/test.csproj new file mode 100644 index 00000000..20827042 --- /dev/null +++ b/examples/test/test.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + diff --git a/src/bindings/client.rs b/src/bindings/client.rs index 44514313..7417ae1b 100644 --- a/src/bindings/client.rs +++ b/src/bindings/client.rs @@ -1,11 +1,6 @@ use runtime::RUNTIME; use openlimits_coinbase::{Coinbase, CoinbaseParameters}; -// use crate::prelude::*; - -pub mod coinbase; - - mod runtime { use ligen_macro::inner_ligen; @@ -61,4 +56,8 @@ impl Client { // response.unwrap() // } // } + + pub fn test() { + println!("Hello from Rust!"); + } } diff --git a/src/bindings/client/coinbase.rs b/src/bindings/client/coinbase.rs deleted file mode 100644 index 1e459b78..00000000 --- a/src/bindings/client/coinbase.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::bindings::string::FFIString; -use crate::bindings::environment::Environment; -use openlimits_coinbase::{CoinbaseParameters, CoinbaseCredentials}; -use ligen::traits::marshalling::MarshalFrom; -use ligen_macro::inner_ligen; - -inner_ligen! { - ffi(CoinbaseParameters(name = "FFICoinbaseParameters")), - marshal( - FFICoinbaseParameters( - name = "CoinbaseParameters" - ) - ), - csharp( - ffi( - FFICoinbaseParameters( - name = "CoinbaseParameters" - ) - ), - ) -} - -#[repr(C, packed(1))] -pub struct FFICoinbaseParameters { - environment: Environment, - apiKey: *mut FFIString, - apiSecret: *mut FFIString, - passphrase: *mut FFIString -} - -impl MarshalFrom for CoinbaseParameters { - fn marshal_from(from: FFICoinbaseParameters) -> Self { - unsafe { - let api_key = String::marshal_from(from.apiKey.read()); - let api_secret = String::marshal_from(from.apiSecret.read()); - let passphrase = String::marshal_from(from.passphrase.read()); - let credentials = if !api_key.is_empty() && !api_secret.is_empty() && !passphrase.is_empty() { - Some(CoinbaseCredentials { api_key, api_secret, passphrase }) - } else { - None - }; - let environment = from.environment.into(); - Self { environment, credentials } - } - } -} \ No newline at end of file diff --git a/src/bindings/mod.rs b/src/bindings/mod.rs index be57d2c2..0baafcc3 100644 --- a/src/bindings/mod.rs +++ b/src/bindings/mod.rs @@ -1,6 +1,5 @@ #![allow(non_snake_case)] -pub mod string; pub mod environment; pub mod client; // pub mod ask_bid; diff --git a/src/bindings/string/mod.rs b/src/bindings/string/mod.rs deleted file mode 100644 index a575cf21..00000000 --- a/src/bindings/string/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -use ligen::traits::marshalling::{MarshalFrom, MarshalInto}; -use ligen_macro::inner_ligen; -use rust_decimal::Decimal; -use std::ffi::{CString, CStr}; - -inner_ligen! { - ffi( - String( - opaque = true, - name = "FFIString" - ), - FFIString(opaque = true) - ), - - csharp( - ffi( - String( - name = "FFIString" - ), - ), - marshal( - FFIString( - methods = "src/bindings/string/string.methods.cs", - ), - String( - name = "string", - methods = "src/bindings/string/string.methods.cs", - ) - ), - ) -} - -pub struct FFIString { - string: CString -} - -impl FFIString { - pub fn new(pointer: *mut i8) -> Self { - let string = unsafe { - CStr::from_ptr(pointer).to_owned() - }; - Self { string } - } - - pub fn get_pointer(&self) -> *const i8 { - self.string.as_ptr() - } -} - -impl MarshalFrom for String { - fn marshal_from(value: FFIString) -> Self { - value.string.to_string_lossy().to_string() - } -} - -impl MarshalFrom for FFIString { - fn marshal_from(value: String) -> Self { - let error = format!("Failed to create CString from String({}).", value); - let string = CString::new(value).expect(&error); - Self { string } - } -} - -impl MarshalFrom for FFIString { - fn marshal_from(value: Decimal) -> Self { - value.to_string().marshal_into() - } -} diff --git a/src/bindings/string/string.methods.cs b/src/bindings/string/string.methods.cs deleted file mode 100644 index d1d44cc8..00000000 --- a/src/bindings/string/string.methods.cs +++ /dev/null @@ -1,17 +0,0 @@ - public static implicit operator string(FFIString from) { - unsafe { - return Marshal.PtrToStringUTF8(from.GetPointer()); - } - } - - public static implicit operator FFIString(string from) { - unsafe { - return FFIString.New(Marshal.StringToHGlobalAnsi(from)); - } - } - - public static implicit operator IntPtr(FFIString from) { - unsafe { - return from.GetPointer(); - } - } diff --git a/src/bindings/vector/mod.rs b/src/bindings/vector/mod.rs deleted file mode 100644 index 823c40cd..00000000 --- a/src/bindings/vector/mod.rs +++ /dev/null @@ -1,54 +0,0 @@ -use ligen_macro::inner_ligen; -use ligen::traits::marshalling::MarshalFrom; -use std::ptr::null_mut; - -inner_ligen! { - ffi(Vec(name = "FFIVector")), - csharp( - ffi( - Vec(name = "FFIVector"), - FFIVector(name = "FFIVector") - ), - marshal( - Vec(name = "List"), - FFIVector( - name = "List", - methods = "src/bindings/vector/vector.methods.cs", - generics = " where T: unmanaged" - ) - ), - ) -} - -#[repr(C)] -pub struct FFIVector { - pub pointer: *mut T, - pub length: u64 -} - -impl Default for FFIVector { - fn default() -> Self { - let pointer = null_mut(); - let length = 0; - Self { pointer, length } - } -} - -impl MarshalFrom> for Vec { - fn marshal_from(from: FFIVector) -> Self { - let length = from.length as usize; - unsafe { - std::slice::from_raw_parts(from.pointer, length).to_vec() - } - } -} - -impl MarshalFrom> for FFIVector { - fn marshal_from(mut from: Vec) -> Self { - let pointer = from.as_mut_ptr(); - let length = from.len() as u64; - // FIXME: Memory leak. - std::mem::forget(from); - Self { pointer, length } - } -} diff --git a/src/bindings/vector/vector.methods.cs b/src/bindings/vector/vector.methods.cs deleted file mode 100644 index 93c824d5..00000000 --- a/src/bindings/vector/vector.methods.cs +++ /dev/null @@ -1,24 +0,0 @@ - public static implicit operator FFIVector(List from) { - var array = from.ToArray(); - ulong length = (ulong) from.Count; - GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); - try { - IntPtr pointer = handle.AddrOfPinnedObject(); - return new FFIVector(pointer, length); - } finally { - // FIXME: Memory leak? It seems to be garbage collected. - // if (handle.IsAllocated) - // handle.Free(); - } - } - - public static implicit operator List(FFIVector from) { - unsafe { - T[] array = new T[from.length]; - fixed (T* apointer = array) { - long length = (long) from.length * (long) sizeof(T); - Buffer.MemoryCopy((void*) from.pointer, (void*) apointer, length, length); - return new List(array); - } - } - } \ No newline at end of file