From 2d9ba85b2aa0b9652a399a1f84cfba3c74a1934c Mon Sep 17 00:00:00 2001 From: Ryan Schmukler Date: Wed, 17 Jul 2019 11:05:22 -0400 Subject: [PATCH] refactor: switch reqs::Order to owned String This commit changes the internals of the `reqs::Order` struct to use an owned struct rather than a lifetime pointer. The main reason for this change is to allow implementing `Into` for structs that don't have pointer-based representations of strings for products. For example, consider the following scenario: ```rust enum Coin { BTC USD } enum Pair { quote: Coin, base: Coin, } enum AppOrder { pair: Pair, size: f64, } ``` If you imagine trying to implement `From for reqs::Order` it is currently impossible, as you would need to render the pair (eg. `format!("{}-{}", pair.quote, pair.base)` but the generated string would not live long enough to satisfy the lifetime requirement of the `Order<'a>`. Since an order is almost always followed by IO, and the frequency of making orders is relatively sparse, the performance overhead of potentially copying a string uneccesarily seems like a worthwhile sacrafice for ergonomics. This commit changes the internals of the `reqs::Order` struct to use an owned struct rather than a lifetime pointer. The main reason for this change is to allow implementing `Into` for structs that don't have pointer-based representations of strings for products. For example, consider the following scenario: ```rust enum Coin { BTC USD } enum Pair { quote: Coin, base: Coin, } enum AppOrder { pair: Pair, size: f64, } ``` If you imagine trying to implement `From for reqs::Order` it is currently impossible, as you would need to render the pair (eg. `format!("{}-{}", pair.quote, pair.base)` but the generated string would not live long enough to satisfy the lifetime requirement of the `Order<'a>`. Since an order is almost always followed by IO, and the frequency of making orders is relatively sparse, the performance overhead of potentially copying a string unnecessarily seems like a worthwhile sacrifice for ergonomics. --- src/structs/reqs.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/structs/reqs.rs b/src/structs/reqs.rs index 18bcb28..3c4a1a7 100644 --- a/src/structs/reqs.rs +++ b/src/structs/reqs.rs @@ -1,10 +1,10 @@ use uuid::Uuid; #[derive(Serialize, Deserialize, Debug)] -pub struct Order<'a> { +pub struct Order { side: OrderSide, client_oid: Option, - product_id: &'a str, + product_id: String, #[serde(flatten)] _type: OrderType, #[serde(flatten)] @@ -43,14 +43,14 @@ pub enum MarketType { Funds { funds: f64 }, } -impl<'a> Order<'a> { +impl Order { pub fn market( - product_id: &'a str, + product_id: &str, side: OrderSide, size: f64, ) -> Self { Order { - product_id, + product_id: product_id.to_owned(), client_oid: None, side, _type: OrderType::Market { @@ -60,23 +60,23 @@ impl<'a> Order<'a> { } } - pub fn buy_market(product_id: &'a str, size: f64) -> Self { - Self::market(product_id, OrderSide::Buy, size) + pub fn buy_market(product_id: &str, size: f64) -> Self { + Self::market(&product_id.to_owned(), OrderSide::Buy, size) } - pub fn sell_market(product_id: &'a str, size: f64) -> Self { - Self::market(product_id, OrderSide::Sell, size) + pub fn sell_market(product_id: &str, size: f64) -> Self { + Self::market(&product_id.to_owned(), OrderSide::Sell, size) } pub fn limit( - product_id: &'a str, + product_id: &str, side: OrderSide, size: f64, price: f64, post_only: bool ) -> Self { Order { - product_id, + product_id: product_id.to_owned(), client_oid: None, side, _type: OrderType::Limit { @@ -89,12 +89,12 @@ impl<'a> Order<'a> { } } - pub fn buy_limit(product_id: &'a str, size: f64, price: f64, post_only: bool) -> Self { - Self::limit(product_id, OrderSide::Buy, size, price, post_only) + pub fn buy_limit(product_id: &str, size: f64, price: f64, post_only: bool) -> Self { + Self::limit(&product_id.to_owned(), OrderSide::Buy, size, price, post_only) } - pub fn sell_limit(product_id: &'a str, size: f64, price: f64, post_only: bool) -> Self { - Self::limit(product_id, OrderSide::Sell, size, price, post_only) + pub fn sell_limit(product_id: &str, size: f64, price: f64, post_only: bool) -> Self { + Self::limit(&product_id.to_owned(), OrderSide::Sell, size, price, post_only) } pub fn client_oid(self, client_oid: Uuid) -> Self {