@@ -24,13 +24,13 @@ build:
|
||||
script:
|
||||
- cargo +nightly build
|
||||
|
||||
# test:
|
||||
# image: registry.karaolidis.com/karaolidis/qrust/rust
|
||||
# stage: test
|
||||
# cache:
|
||||
# <<: *global_cache
|
||||
# script:
|
||||
# - cargo +nightly test
|
||||
test:
|
||||
image: registry.karaolidis.com/karaolidis/qrust/rust
|
||||
stage: test
|
||||
cache:
|
||||
<<: *global_cache
|
||||
script:
|
||||
- cargo +nightly test
|
||||
|
||||
lint:
|
||||
image: registry.karaolidis.com/karaolidis/qrust/rust
|
||||
|
102
Cargo.lock
generated
102
Cargo.lock
generated
@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -55,13 +55,13 @@ checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.77"
|
||||
version = "0.1.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
||||
checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -168,9 +168,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.2"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@@ -233,6 +233,15 @@ dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "claims"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6995bbe186456c36307f8ea36be3eefe42f49d106896414e18efc4fb2f846b5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clickhouse"
|
||||
version = "0.11.6"
|
||||
@@ -342,7 +351,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -353,7 +362,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -541,7 +550,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -629,9 +638,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
|
||||
checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@@ -648,9 +657,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943"
|
||||
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@@ -782,7 +791,7 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.24",
|
||||
"h2 0.3.25",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"httparse",
|
||||
@@ -805,7 +814,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2 0.4.2",
|
||||
"h2 0.4.3",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"httparse",
|
||||
@@ -1168,7 +1177,7 @@ version = "0.10.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@@ -1185,7 +1194,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1261,7 +1270,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1316,6 +1325,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"backoff",
|
||||
"claims",
|
||||
"clickhouse",
|
||||
"dotenv",
|
||||
"futures-util",
|
||||
@@ -1332,6 +1342,7 @@ dependencies = [
|
||||
"serde-aux",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"serde_test",
|
||||
"serde_with",
|
||||
"time",
|
||||
"tokio",
|
||||
@@ -1399,7 +1410,7 @@ version = "11.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1442,16 +1453,16 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.26"
|
||||
version = "0.11.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2"
|
||||
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.24",
|
||||
"h2 0.3.25",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
@@ -1488,11 +1499,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.31"
|
||||
version = "0.38.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@@ -1608,7 +1619,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1651,7 +1662,16 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_test"
|
||||
version = "1.0.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1693,14 +1713,14 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.32"
|
||||
version = "0.9.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f"
|
||||
checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"itoa",
|
||||
@@ -1790,9 +1810,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
version = "2.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1855,7 +1875,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1941,7 +1961,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2109,9 +2129,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.10"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
@@ -2132,9 +2152,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
|
||||
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
@@ -2188,7 +2208,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -2222,7 +2242,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@@ -71,3 +71,7 @@ lazy_static = "1.4.0"
|
||||
nonempty = { version = "0.10.0", features = [
|
||||
"serialize",
|
||||
] }
|
||||
|
||||
[dev-dependencies]
|
||||
claims = "0.7.1"
|
||||
serde_test = "1.0.176"
|
||||
|
@@ -13,3 +13,14 @@ pub fn strip(content: &str) -> String {
|
||||
let content = content.trim();
|
||||
content.to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_strip() {
|
||||
let content = "<p> <b> Hello, </b> <i> World! </i> </p>";
|
||||
assert_eq!(strip(content), "Hello, World!");
|
||||
}
|
||||
}
|
||||
|
@@ -223,3 +223,53 @@ impl Order {
|
||||
orders
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_normalize() {
|
||||
let order_template = Order {
|
||||
id: Uuid::new_v4(),
|
||||
client_order_id: Uuid::new_v4(),
|
||||
created_at: OffsetDateTime::now_utc(),
|
||||
updated_at: None,
|
||||
submitted_at: OffsetDateTime::now_utc(),
|
||||
filled_at: None,
|
||||
expired_at: None,
|
||||
cancel_requested_at: None,
|
||||
canceled_at: None,
|
||||
failed_at: None,
|
||||
replaced_at: None,
|
||||
replaced_by: None,
|
||||
replaces: None,
|
||||
asset_id: Uuid::new_v4(),
|
||||
symbol: "AAPL".to_string(),
|
||||
asset_class: super::super::asset::Class::UsEquity,
|
||||
notional: None,
|
||||
qty: None,
|
||||
filled_qty: 0.0,
|
||||
filled_avg_price: None,
|
||||
order_class: Class::Simple,
|
||||
order_type: Type::Market,
|
||||
side: Side::Buy,
|
||||
time_in_force: TimeInForce::Day,
|
||||
limit_price: None,
|
||||
stop_price: None,
|
||||
status: Status::New,
|
||||
extended_hours: false,
|
||||
legs: None,
|
||||
trail_percent: None,
|
||||
trail_price: None,
|
||||
hwm: None,
|
||||
};
|
||||
|
||||
let mut order = order_template.clone();
|
||||
order.legs = Some(vec![order_template.clone(), order_template.clone()]);
|
||||
order.legs.as_mut().unwrap()[0].legs = Some(vec![order_template.clone()]);
|
||||
let orders = order.normalize();
|
||||
|
||||
assert_eq!(orders.len(), 4);
|
||||
}
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ where
|
||||
struct TimeVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for TimeVisitor {
|
||||
type Value = time::Time;
|
||||
type Value = Time;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a string in the format HH:MM")
|
||||
@@ -102,3 +102,92 @@ where
|
||||
|
||||
deserializer.deserialize_str(TimeVisitor)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::Deserialize;
|
||||
use serde_test::{assert_de_tokens, Token};
|
||||
use time::Time;
|
||||
|
||||
#[test]
|
||||
fn test_add_slash() {
|
||||
assert_eq!(add_slash("BTCUSD"), "BTC/USD");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_slash_skip() {
|
||||
assert_eq!(add_slash("ABTC"), "ABTC");
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
struct AddSlashToSymbol {
|
||||
#[serde(deserialize_with = "add_slash_to_symbol")]
|
||||
symbol: String,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_slash_to_symbol() {
|
||||
assert_de_tokens::<AddSlashToSymbol>(
|
||||
&AddSlashToSymbol {
|
||||
symbol: String::from("BTC/USD"),
|
||||
},
|
||||
&[Token::Str("BTCUSD")],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_slash_to_symbol_skip() {
|
||||
assert_de_tokens::<AddSlashToSymbol>(
|
||||
&AddSlashToSymbol {
|
||||
symbol: String::from("ABTC"),
|
||||
},
|
||||
&[Token::Str("ABTC")],
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
struct AddSlashToSymbols {
|
||||
#[serde(deserialize_with = "add_slash_to_symbols")]
|
||||
symbols: Vec<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_slash_to_symbols() {
|
||||
assert_de_tokens::<AddSlashToSymbols>(
|
||||
&AddSlashToSymbols {
|
||||
symbols: vec![
|
||||
String::from("BTC/USD"),
|
||||
String::from("ETH/USD"),
|
||||
String::from("ABTC"),
|
||||
],
|
||||
},
|
||||
&[
|
||||
Token::Seq { len: Some(3) },
|
||||
Token::Str("BTCUSD"),
|
||||
Token::Str("ETHUSD"),
|
||||
Token::Str("ABTC"),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
struct HumanTime {
|
||||
#[serde(deserialize_with = "human_time_hh_mm")]
|
||||
time: Time,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_human_time_hh_mm() {
|
||||
assert_de_tokens::<HumanTime>(
|
||||
&HumanTime {
|
||||
time: Time::from_hms(12, 34, 0).unwrap(),
|
||||
},
|
||||
&[Token::Str("12:34")],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -5,27 +5,48 @@ pub fn timeframe<S>(timeframe: &Duration, serializer: S) -> Result<S::Ok, S::Err
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mins = timeframe.as_secs() / 60;
|
||||
let secs = timeframe.as_secs();
|
||||
|
||||
if secs < 60 || secs % 60 != 0 {
|
||||
return Err(serde::ser::Error::custom("Invalid timeframe duration"));
|
||||
}
|
||||
|
||||
let mins = secs / 60;
|
||||
|
||||
if mins < 60 {
|
||||
return serializer.serialize_str(&format!("{mins}Min"));
|
||||
}
|
||||
|
||||
if mins % 60 != 0 {
|
||||
return Err(serde::ser::Error::custom("Invalid timeframe duration"));
|
||||
}
|
||||
|
||||
let hours = mins / 60;
|
||||
|
||||
if hours < 24 {
|
||||
return serializer.serialize_str(&format!("{hours}Hour"));
|
||||
}
|
||||
|
||||
if hours % 24 != 0 {
|
||||
return Err(serde::ser::Error::custom("Invalid timeframe duration"));
|
||||
}
|
||||
|
||||
let days = hours / 24;
|
||||
|
||||
if days == 1 {
|
||||
return serializer.serialize_str("1Day");
|
||||
}
|
||||
|
||||
let weeks = days / 7;
|
||||
if weeks == 1 {
|
||||
if days == 7 {
|
||||
return serializer.serialize_str("1Week");
|
||||
}
|
||||
|
||||
if days < 30 || days % 30 != 0 {
|
||||
return Err(serde::ser::Error::custom("Invalid timeframe duration"));
|
||||
}
|
||||
|
||||
let months = days / 30;
|
||||
|
||||
if [1, 2, 3, 4, 6, 12].contains(&months) {
|
||||
return serializer.serialize_str(&format!("{months}Month"));
|
||||
};
|
||||
@@ -87,3 +108,174 @@ where
|
||||
|
||||
join_symbols(&symbols, serializer)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::Serialize;
|
||||
use serde_test::{assert_ser_tokens, assert_ser_tokens_error, Token};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(transparent)]
|
||||
struct Timeframe {
|
||||
#[serde(serialize_with = "timeframe")]
|
||||
duration: Duration,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_30_mins() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 30),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&timeframe, &[Token::Str("30Min")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_2_hours() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 60 * 2),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&timeframe, &[Token::Str("2Hour")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_1_day() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 60 * 24),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&timeframe, &[Token::Str("1Day")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_1_week() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 60 * 24 * 7),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&timeframe, &[Token::Str("1Week")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_6_months() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 60 * 24 * 30 * 6),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&timeframe, &[Token::Str("6Month")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_invalid_1_second() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(1),
|
||||
};
|
||||
|
||||
assert_ser_tokens_error(&timeframe, &[], "Invalid timeframe duration");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_invalid_61_seconds() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(61),
|
||||
};
|
||||
|
||||
assert_ser_tokens_error(&timeframe, &[], "Invalid timeframe duration");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timeframe_invalid_6_days() {
|
||||
let timeframe = Timeframe {
|
||||
duration: Duration::from_secs(60 * 60 * 24 * 6),
|
||||
};
|
||||
|
||||
assert_ser_tokens_error(&timeframe, &[], "Invalid timeframe duration");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_slash() {
|
||||
let pair = "BTC/USDT";
|
||||
assert_eq!(remove_slash(pair), "BTCUSDT");
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(transparent)]
|
||||
struct JoinSymbols {
|
||||
#[serde(serialize_with = "join_symbols")]
|
||||
symbols: Vec<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_join_symbols() {
|
||||
let symbols = JoinSymbols {
|
||||
symbols: vec![String::from("BTC/USD"), String::from("ETH/USD")],
|
||||
};
|
||||
|
||||
assert_ser_tokens(&symbols, &[Token::Str("BTC/USD,ETH/USD")]);
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(transparent)]
|
||||
struct JoinSymbolsOption {
|
||||
#[serde(serialize_with = "join_symbols_option")]
|
||||
symbols: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_join_symbols_option_some() {
|
||||
let symbols = JoinSymbolsOption {
|
||||
symbols: Some(vec![String::from("BTC/USD"), String::from("ETH/USD")]),
|
||||
};
|
||||
|
||||
assert_ser_tokens(&symbols, &[Token::Str("BTC/USD,ETH/USD")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_join_symbols_option_none() {
|
||||
let symbols = JoinSymbolsOption { symbols: None };
|
||||
|
||||
assert_ser_tokens(&symbols, &[Token::None]);
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(transparent)]
|
||||
struct RemoveSlashFromSymbols {
|
||||
#[serde(serialize_with = "remove_slash_from_symbols")]
|
||||
symbols: Vec<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_slash_from_symbols() {
|
||||
let symbols = RemoveSlashFromSymbols {
|
||||
symbols: vec![String::from("BTC/USD"), String::from("ETH/USD")],
|
||||
};
|
||||
|
||||
assert_ser_tokens(
|
||||
&symbols,
|
||||
&[
|
||||
Token::Seq { len: Some(2) },
|
||||
Token::Str("BTCUSD"),
|
||||
Token::Str("ETHUSD"),
|
||||
Token::SeqEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(transparent)]
|
||||
struct RemoveSlashAndJoinSymbols {
|
||||
#[serde(serialize_with = "remove_slash_and_join_symbols")]
|
||||
symbols: Vec<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_slash_and_join_symbols() {
|
||||
let symbols = RemoveSlashAndJoinSymbols {
|
||||
symbols: vec![String::from("BTC/USD"), String::from("ETH/USD")],
|
||||
};
|
||||
|
||||
assert_ser_tokens(&symbols, &[Token::Str("BTCUSD,ETHUSD")]);
|
||||
}
|
||||
}
|
||||
|
@@ -26,3 +26,21 @@ pub fn duration_until(time: OffsetDateTime) -> Duration {
|
||||
Duration::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_duration_until_future() {
|
||||
let future = OffsetDateTime::now_utc() + Duration::from_secs(60);
|
||||
let duration = duration_until(future).as_secs();
|
||||
assert!((59..=61).contains(&duration));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duration_until_past() {
|
||||
let past = OffsetDateTime::now_utc() - Duration::from_secs(60);
|
||||
assert_eq!(duration_until(past).as_secs(), 0);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user