Skip to content

Commit

Permalink
refactor: switch reqs::Order to owned String
Browse files Browse the repository at this point in the history
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<Order>` 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<AppOrder> 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<Order>` 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<AppOrder> 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.
  • Loading branch information
rschmukler committed Jul 17, 2019
1 parent 8894365 commit 2d9ba85
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions 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<Uuid>,
product_id: &'a str,
product_id: String,
#[serde(flatten)]
_type: OrderType,
#[serde(flatten)]
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit 2d9ba85

Please sign in to comment.