<commit_before>use std::fmt;

#[derive(Debug)]
pub enum BittrexOrderType {
    Sell,
    Buy,
    Both,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAPIResult<T> {
    pub success: bool,
    pub message: String,
    pub result: Option<T>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAPIVecResult<T> {
    pub success: bool,
    pub message: String,
    pub result: Option<Vec<T>>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexUuid {
    #[serde(rename = "uuid")]
    pub uuid: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAddress {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Address")]
    pub address: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexCurrency {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "CurrencyLong")]
    pub currency_long: String,
    #[serde(rename = "MinConfirmation")]
    pub min_confirmation: u32,
    #[serde(rename = "TxFee")]
    pub tx_fee: f32,
    #[serde(rename = "IsActive")]
    pub is_active: bool,
    #[serde(rename = "CoinType")]
    pub coin_type: Option<String>,
    #[serde(rename = "BaseAddress")]
    pub base_address: Option<String>,
    #[serde(rename = "Notice")]
    pub notice: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexMarket {
    #[serde(rename = "MarketCurrency")]
    pub market_currency: String,
    #[serde(rename = "BaseCurrency")]
    pub base_currency: String,
    #[serde(rename = "MarketCurrencyLong")]
    pub market_currency_long: String,
    #[serde(rename = "BaseCurrencyLong")]
    pub base_currency_long: String,
    #[serde(rename = "MinTradeSize")]
    pub min_trade_size: f32,
    #[serde(rename = "MarketName")]
    pub market_name: String,
    #[serde(rename = "IsActive")]
    pub is_active: bool,
    #[serde(rename = "Created")]
    pub created: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexMarketSummary {
    #[serde(rename = "MarketName")]
    pub market_name: String,
    #[serde(rename = "High")]
    pub high: f32,
    #[serde(rename = "Low")]
    pub low: f32,
    #[serde(rename = "Volume")]
    pub volume: f64,
    #[serde(rename = "Last")]
    pub last: f64,
    #[serde(rename = "BaseVolume")]
    pub base_volume: f64,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "Bid")]
    pub bid: f32,
    #[serde(rename = "Ask")]
    pub ask: f32,
    #[serde(rename = "OpenBuyOrders")]
    pub open_buy_orders: u32,
    #[serde(rename = "OpenSellOrders")]
    pub open_sell_orders: u32,
    #[serde(rename = "PrevDay")]
    pub prev_day: f32,
    #[serde(rename = "Created")]
    pub created: String,
    #[serde(rename = "DisplayMarketName")]
    pub display_market_name: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTicker {
    #[serde(rename = "Ask")]
    pub ask: f32,
    #[serde(rename = "Bid")]
    pub bid: f32,
    #[serde(rename = "Last")]
    pub last: f32,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexPublicOrderBook {
    #[serde(rename = "buy")]
    pub buy: Vec<BittrexPublicOrder>,
    #[serde(rename = "sell")]
    pub sell: Vec<BittrexPublicOrder>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexPublicOrder {
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "Rate")]
    pub rate: f32,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTrade {
    #[serde(rename = "Id")]
    pub id: u32,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "Total")]
    pub total: f32,
    #[serde(rename = "FillType")]
    pub fill_type: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexOpenOrder {
    #[serde(rename = "Uuid")]
    pub uuid: Option<String>,
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "CommissionPaid")]
    pub comission_paid: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Closed")]
    pub closed: Option<String>,
    #[serde(rename = "CancelInitiated")]
    pub cancel_initiated: bool,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexHistoryOrder {
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "Commission")]
    pub comission: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexOrder {
    #[serde(rename = "AccountId")]
    pub account_id: Option<String>,
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "Type")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "Reserved")]
    pub reserved: f32,
    #[serde(rename = "ReserveRemaining")]
    pub reserve_remaining: f32,
    #[serde(rename = "CommissionReserved")]
    pub commission_reserved: f32,
    #[serde(rename = "CommissionReserveRemaining")]
    pub commission_reserve_remaining: f32,
    #[serde(rename = "CommissionPaid")]
    pub comission_paid: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Closed")]
    pub closed: Option<String>,
    #[serde(rename = "IsOpen")]
    pub is_open: bool,
    #[serde(rename = "Sentinel")]
    pub sentinel: String,
    #[serde(rename = "CancelInitiated")]
    pub cancel_initiated: bool,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTransaction {
    #[serde(rename = "PaymentUuid")]
    pub payment_uuid: String,
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Amount")]
    pub amount: f32,
    #[serde(rename = "Address")]
    pub address: String,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Authorized")]
    pub authorized: bool,
    #[serde(rename = "PendingPayment")]
    pub pending_payment: bool,
    #[serde(rename = "TxCost")]
    pub tx_cost: f32,
    #[serde(rename = "TxId")]
    pub tx_id: Option<String>,
    #[serde(rename = "Canceled")]
    pub canceled: bool,
    #[serde(rename = "InvalidAddress")]
    pub invalid_address: bool,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexBalance {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Balance")]
    pub balance: f32,
    #[serde(rename = "Available")]
    pub available: f32,
    #[serde(rename = "Pending")]
    pub pending: f32,
    #[serde(rename = "CryptoAddress")]
    pub crypto_address: String,
}

impl fmt::Display for BittrexOrderType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl fmt::Display for BittrexUuid {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.uuid)
    }
}

impl fmt::Display for BittrexAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Currency: {} (Address: {})", self.currency, self.address)
    }
}

impl fmt::Display for BittrexCurrency {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (Min. Confirmations: {}, Tx Fee: {})",
            self.currency,
            self.min_confirmation,
            self.tx_fee
        )
    }
}

impl fmt::Display for BittrexMarket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (Min. Trade Size: {})",
            self.market_name,
            self.min_trade_size
        )
    }
}

impl fmt::Display for BittrexMarketSummary {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (High: {}, Low: {}, Volume: {})",
            self.market_name,
            self.high,
            self.low,
            self.volume
        )
    }
}

impl fmt::Display for BittrexTicker {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(Ask: {}, Bid: {}, Last: {})",
            self.ask,
            self.bid,
            self.last
        )
    }
}

impl fmt::Display for BittrexPublicOrderBook {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(Buy Quantity: {}, Sell Quantity: {})",
            self.buy.len(),
            self.sell.len()
        )
    }
}

impl fmt::Display for BittrexPublicOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "(Quantity: {}, Rate: {})", self.quantity, self.rate)
    }
}

impl fmt::Display for BittrexTrade {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "ID: {} (Quantity: {}, Price: {}, Total: {})",
            self.id,
            self.quantity,
            self.price,
            self.total
        )
    }
}

impl fmt::Display for BittrexOpenOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Order Type: {}, Quantity: {}, Limit: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit
        )
    }
}

impl fmt::Display for BittrexHistoryOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Type: {}, Quantity: {}, Limit: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit
        )
    }
}

impl fmt::Display for BittrexOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Type: {}, Quantity: {}, Limit: {}, Is Open: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit,
            self.is_open
        )
    }
}

impl fmt::Display for BittrexTransaction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Currency: {}, Ammount: {}, Address: {}, Pending: {})",
            self.payment_uuid,
            self.currency,
            self.amount,
            self.address,
            self.pending_payment
        )
    }
}

impl fmt::Display for BittrexBalance {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Currency: {} (Balance: {}, Available: {}, Pending: {})",
            self.currency,
            self.balance,
            self.available,
            self.pending
        )
    }
}
<commit_msg>allowed nullable values for crypto_address field in get_balances request.<commit_after>use std::fmt;

#[derive(Debug)]
pub enum BittrexOrderType {
    Sell,
    Buy,
    Both,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAPIResult<T> {
    pub success: bool,
    pub message: String,
    pub result: Option<T>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAPIVecResult<T> {
    pub success: bool,
    pub message: String,
    pub result: Option<Vec<T>>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexUuid {
    #[serde(rename = "uuid")]
    pub uuid: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexAddress {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Address")]
    pub address: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexCurrency {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "CurrencyLong")]
    pub currency_long: String,
    #[serde(rename = "MinConfirmation")]
    pub min_confirmation: u32,
    #[serde(rename = "TxFee")]
    pub tx_fee: f32,
    #[serde(rename = "IsActive")]
    pub is_active: bool,
    #[serde(rename = "CoinType")]
    pub coin_type: Option<String>,
    #[serde(rename = "BaseAddress")]
    pub base_address: Option<String>,
    #[serde(rename = "Notice")]
    pub notice: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexMarket {
    #[serde(rename = "MarketCurrency")]
    pub market_currency: String,
    #[serde(rename = "BaseCurrency")]
    pub base_currency: String,
    #[serde(rename = "MarketCurrencyLong")]
    pub market_currency_long: String,
    #[serde(rename = "BaseCurrencyLong")]
    pub base_currency_long: String,
    #[serde(rename = "MinTradeSize")]
    pub min_trade_size: f32,
    #[serde(rename = "MarketName")]
    pub market_name: String,
    #[serde(rename = "IsActive")]
    pub is_active: bool,
    #[serde(rename = "Created")]
    pub created: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexMarketSummary {
    #[serde(rename = "MarketName")]
    pub market_name: String,
    #[serde(rename = "High")]
    pub high: f32,
    #[serde(rename = "Low")]
    pub low: f32,
    #[serde(rename = "Volume")]
    pub volume: f64,
    #[serde(rename = "Last")]
    pub last: f64,
    #[serde(rename = "BaseVolume")]
    pub base_volume: f64,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "Bid")]
    pub bid: f32,
    #[serde(rename = "Ask")]
    pub ask: f32,
    #[serde(rename = "OpenBuyOrders")]
    pub open_buy_orders: u32,
    #[serde(rename = "OpenSellOrders")]
    pub open_sell_orders: u32,
    #[serde(rename = "PrevDay")]
    pub prev_day: f32,
    #[serde(rename = "Created")]
    pub created: String,
    #[serde(rename = "DisplayMarketName")]
    pub display_market_name: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTicker {
    #[serde(rename = "Ask")]
    pub ask: f32,
    #[serde(rename = "Bid")]
    pub bid: f32,
    #[serde(rename = "Last")]
    pub last: f32,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexPublicOrderBook {
    #[serde(rename = "buy")]
    pub buy: Vec<BittrexPublicOrder>,
    #[serde(rename = "sell")]
    pub sell: Vec<BittrexPublicOrder>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexPublicOrder {
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "Rate")]
    pub rate: f32,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTrade {
    #[serde(rename = "Id")]
    pub id: u32,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "Total")]
    pub total: f32,
    #[serde(rename = "FillType")]
    pub fill_type: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexOpenOrder {
    #[serde(rename = "Uuid")]
    pub uuid: Option<String>,
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "CommissionPaid")]
    pub comission_paid: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Closed")]
    pub closed: Option<String>,
    #[serde(rename = "CancelInitiated")]
    pub cancel_initiated: bool,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexHistoryOrder {
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "TimeStamp")]
    pub time_stamp: String,
    #[serde(rename = "OrderType")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "Commission")]
    pub comission: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexOrder {
    #[serde(rename = "AccountId")]
    pub account_id: Option<String>,
    #[serde(rename = "OrderUuid")]
    pub order_uuid: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "Type")]
    pub order_type: String,
    #[serde(rename = "Quantity")]
    pub quantity: f32,
    #[serde(rename = "QuantityRemaining")]
    pub quantity_remaining: f32,
    #[serde(rename = "Limit")]
    pub limit: f32,
    #[serde(rename = "Reserved")]
    pub reserved: f32,
    #[serde(rename = "ReserveRemaining")]
    pub reserve_remaining: f32,
    #[serde(rename = "CommissionReserved")]
    pub commission_reserved: f32,
    #[serde(rename = "CommissionReserveRemaining")]
    pub commission_reserve_remaining: f32,
    #[serde(rename = "CommissionPaid")]
    pub comission_paid: f32,
    #[serde(rename = "Price")]
    pub price: f32,
    #[serde(rename = "PricePerUnit")]
    pub price_per_unit: Option<f32>,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Closed")]
    pub closed: Option<String>,
    #[serde(rename = "IsOpen")]
    pub is_open: bool,
    #[serde(rename = "Sentinel")]
    pub sentinel: String,
    #[serde(rename = "CancelInitiated")]
    pub cancel_initiated: bool,
    #[serde(rename = "ImmediateOrCancel")]
    pub immediate_or_cancel: bool,
    #[serde(rename = "IsConditional")]
    pub is_conditional: bool,
    #[serde(rename = "Condition")]
    pub condition: Option<String>,
    #[serde(rename = "ConditionalTarget")]
    pub conditional_target: Option<String>,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexTransaction {
    #[serde(rename = "PaymentUuid")]
    pub payment_uuid: String,
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Amount")]
    pub amount: f32,
    #[serde(rename = "Address")]
    pub address: String,
    #[serde(rename = "Opened")]
    pub opened: String,
    #[serde(rename = "Authorized")]
    pub authorized: bool,
    #[serde(rename = "PendingPayment")]
    pub pending_payment: bool,
    #[serde(rename = "TxCost")]
    pub tx_cost: f32,
    #[serde(rename = "TxId")]
    pub tx_id: Option<String>,
    #[serde(rename = "Canceled")]
    pub canceled: bool,
    #[serde(rename = "InvalidAddress")]
    pub invalid_address: bool,
}

#[derive(Serialize, Deserialize)]
pub struct BittrexBalance {
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Balance")]
    pub balance: f32,
    #[serde(rename = "Available")]
    pub available: f32,
    #[serde(rename = "Pending")]
    pub pending: f32,
    #[serde(rename = "CryptoAddress")]
    pub crypto_address: Option<String>,
}

impl fmt::Display for BittrexOrderType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl fmt::Display for BittrexUuid {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.uuid)
    }
}

impl fmt::Display for BittrexAddress {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Currency: {} (Address: {})", self.currency, self.address)
    }
}

impl fmt::Display for BittrexCurrency {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (Min. Confirmations: {}, Tx Fee: {})",
            self.currency,
            self.min_confirmation,
            self.tx_fee
        )
    }
}

impl fmt::Display for BittrexMarket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (Min. Trade Size: {})",
            self.market_name,
            self.min_trade_size
        )
    }
}

impl fmt::Display for BittrexMarketSummary {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{} (High: {}, Low: {}, Volume: {})",
            self.market_name,
            self.high,
            self.low,
            self.volume
        )
    }
}

impl fmt::Display for BittrexTicker {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(Ask: {}, Bid: {}, Last: {})",
            self.ask,
            self.bid,
            self.last
        )
    }
}

impl fmt::Display for BittrexPublicOrderBook {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "(Buy Quantity: {}, Sell Quantity: {})",
            self.buy.len(),
            self.sell.len()
        )
    }
}

impl fmt::Display for BittrexPublicOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "(Quantity: {}, Rate: {})", self.quantity, self.rate)
    }
}

impl fmt::Display for BittrexTrade {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "ID: {} (Quantity: {}, Price: {}, Total: {})",
            self.id,
            self.quantity,
            self.price,
            self.total
        )
    }
}

impl fmt::Display for BittrexOpenOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Order Type: {}, Quantity: {}, Limit: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit
        )
    }
}

impl fmt::Display for BittrexHistoryOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Type: {}, Quantity: {}, Limit: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit
        )
    }
}

impl fmt::Display for BittrexOrder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Exchange: {}, Type: {}, Quantity: {}, Limit: {}, Is Open: {})",
            self.order_uuid,
            self.exchange,
            self.order_type,
            self.quantity,
            self.limit,
            self.is_open
        )
    }
}

impl fmt::Display for BittrexTransaction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Uuid: {} (Currency: {}, Ammount: {}, Address: {}, Pending: {})",
            self.payment_uuid,
            self.currency,
            self.amount,
            self.address,
            self.pending_payment
        )
    }
}

impl fmt::Display for BittrexBalance {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Currency: {} (Balance: {}, Available: {}, Pending: {})",
            self.currency,
            self.balance,
            self.available,
            self.pending
        )
    }
}
<|endoftext|>


<commit_before>/// Representation of a mathematical vector e.g. a position or velocity
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Vector2<T>(pub T, pub T);

use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, Div, Neg};
use std::convert::From;

/// Special methods for floating point vectors
pub trait FloatVector<F>{
    /// Creates a new unit vector in a specific direction
    fn unit_vector(F) -> Self;
    /// Normalises the vector
    fn normalise(self) -> Self;
    /// Returns the magnitude or the length of the vector
    fn length(&self) -> F;
    /// Returns direction the vector is pointing
    fn direction(&self) -> F;
    /// Returns direction towards another vector
    fn direction_to(&self, &Self) -> F;
    /// Returns the distance betweens two vectors
    fn distance_to(&self, &Self) -> F;
}

macro_rules! impl_for {
    ($($t:ty)*) => {$(
        impl FloatVector<$t> for Vector2<$t>{
            fn unit_vector(direction: $t) -> Self{
                let (y, x) = direction.sin_cos();
                Vector2(x, y)
            }

            fn normalise(self) -> Self{
                let length = self.length();
                self / length
            }

            fn length(&self) -> $t{
                self.0.hypot(self.1)
            }

            fn direction(&self) -> $t{
                (-self.1).atan2(self.0)
            }

            fn direction_to(&self, other: &Self) -> $t{
                (*other-*self).direction()
            }

            fn distance_to(&self, other: &Self) -> $t{
                (self.0 - other.0).hypot(self.1 - other.1)
            }
        }

        impl Mul<Vector2<$t>> for $t{
            type Output = Vector2<$t>;

            fn mul(self, rhs: Vector2<$t>) -> Vector2<$t>{
                Vector2(self * rhs.0, self * rhs.1)
            }
        }

        impl Div<Vector2<$t>> for $t{
            type Output = Vector2<$t>;

            fn div(self, rhs: Vector2<$t>) -> Vector2<$t>{
                Vector2(self / rhs.0, self / rhs.1)
            }
        }
    )*};
}

impl_for!(f32 f64);

impl<T> Vector2<T> {
    /// Returns the dot product of two vectors
    pub fn dot(self, other: Self) -> T where T: Mul<Output=T> + Add<Output=T>{
        self.0 * other.0 + self.1 * other.1
    }
    /// Returns the fields in a tuple
    pub fn to_tuple(self) -> (T, T){
        (self.0, self.1)
    }
    /// Returns an array of the two fields
    pub fn to_array(self) -> [T; 2]{
        [self.0, self.1]
    }
}

impl<T: Add<Output=T>> Add for Vector2<T>{
    type Output = Self;

    fn add(self, rhs: Self) -> Self{
        Vector2(self.0 + rhs.0, self.1 + rhs.1)
    }
}

impl<T: Sub<Output=T>> Sub for Vector2<T>{
    type Output = Self;

    fn sub(self, rhs: Self) -> Self{
        Vector2(self.0 - rhs.0, self.1 - rhs.1)
    }
}

impl<T: AddAssign> AddAssign for Vector2<T>{
    fn add_assign(&mut self, rhs: Self){
        self.0 += rhs.0;
        self.1 += rhs.1;
    }
}

impl<T: SubAssign> SubAssign for Vector2<T>{
    fn sub_assign(&mut self, rhs: Self){
        self.0 -= rhs.0;
        self.1 -= rhs.1;
    }
}

impl<T: Mul<Output=T> + Copy> Mul<T> for Vector2<T>{
    type Output = Self;

    fn mul(self, rhs: T) -> Self{
        Vector2(self.0 * rhs, self.1 * rhs)
    }
}

impl<T: Div<Output=T> + Copy> Div<T> for Vector2<T>{
    type Output = Self;

    fn div(self, rhs: T) -> Self{
        Vector2(self.0/rhs, self.1/rhs)
    }
}

impl<T: Neg<Output=T>> Neg for Vector2<T>{
    type Output = Self;

    fn neg(self) -> Self{
        Vector2(-self.0, -self.1)
    }
}

impl<T> Into<(T, T)> for Vector2<T>{
    #[inline(always)]
    fn into(self) -> (T, T){
        self.to_tuple()
    }
}

impl<T> From<(T, T)> for Vector2<T>{
    #[inline(always)]
    fn from(tuple: (T, T)) -> Self{
        Vector2(tuple.0, tuple.1)
    }
}
<commit_msg>Use traits for converting into and from Vector2<commit_after>/// Representation of a mathematical vector e.g. a position or velocity
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Vector2<T>(pub T, pub T);

use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, Div, Neg};
use std::convert::From;

/// Special methods for floating point vectors
pub trait FloatVector<F>{
    /// Creates a new unit vector in a specific direction
    fn unit_vector(F) -> Self;
    /// Normalises the vector
    fn normalise(self) -> Self;
    /// Returns the magnitude or the length of the vector
    fn length(&self) -> F;
    /// Returns direction the vector is pointing
    fn direction(&self) -> F;
    /// Returns direction towards another vector
    fn direction_to(&self, &Self) -> F;
    /// Returns the distance betweens two vectors
    fn distance_to(&self, &Self) -> F;
}

macro_rules! impl_for {
    ($($t:ty)*) => {$(
        impl FloatVector<$t> for Vector2<$t>{
            fn unit_vector(direction: $t) -> Self{
                let (y, x) = direction.sin_cos();
                Vector2(x, y)
            }

            fn normalise(self) -> Self{
                let length = self.length();
                self / length
            }

            fn length(&self) -> $t{
                self.0.hypot(self.1)
            }

            fn direction(&self) -> $t{
                (-self.1).atan2(self.0)
            }

            fn direction_to(&self, other: &Self) -> $t{
                (*other-*self).direction()
            }

            fn distance_to(&self, other: &Self) -> $t{
                (self.0 - other.0).hypot(self.1 - other.1)
            }
        }

        impl Mul<Vector2<$t>> for $t{
            type Output = Vector2<$t>;

            fn mul(self, rhs: Vector2<$t>) -> Vector2<$t>{
                Vector2(self * rhs.0, self * rhs.1)
            }
        }

        impl Div<Vector2<$t>> for $t{
            type Output = Vector2<$t>;

            fn div(self, rhs: Vector2<$t>) -> Vector2<$t>{
                Vector2(self / rhs.0, self / rhs.1)
            }
        }
    )*};
}

impl_for!(f32 f64);

impl<T> Vector2<T> {
    /// Returns the dot product of two vectors
    pub fn dot(self, other: Self) -> T where T: Mul<Output=T> + Add<Output=T>{
        self.0 * other.0 + self.1 * other.1
    }
}

impl<T: Add<Output=T>> Add for Vector2<T>{
    type Output = Self;

    fn add(self, rhs: Self) -> Self{
        Vector2(self.0 + rhs.0, self.1 + rhs.1)
    }
}

impl<T: Sub<Output=T>> Sub for Vector2<T>{
    type Output = Self;

    fn sub(self, rhs: Self) -> Self{
        Vector2(self.0 - rhs.0, self.1 - rhs.1)
    }
}

impl<T: AddAssign> AddAssign for Vector2<T>{
    fn add_assign(&mut self, rhs: Self){
        self.0 += rhs.0;
        self.1 += rhs.1;
    }
}

impl<T: SubAssign> SubAssign for Vector2<T>{
    fn sub_assign(&mut self, rhs: Self){
        self.0 -= rhs.0;
        self.1 -= rhs.1;
    }
}

impl<T: Mul<Output=T> + Copy> Mul<T> for Vector2<T>{
    type Output = Self;

    fn mul(self, rhs: T) -> Self{
        Vector2(self.0 * rhs, self.1 * rhs)
    }
}

impl<T: Div<Output=T> + Copy> Div<T> for Vector2<T>{
    type Output = Self;

    fn div(self, rhs: T) -> Self{
        Vector2(self.0/rhs, self.1/rhs)
    }
}

impl<T: Neg<Output=T>> Neg for Vector2<T>{
    type Output = Self;

    fn neg(self) -> Self{
        Vector2(-self.0, -self.1)
    }
}

impl<T> Into<[T; 2]> for Vector2<T>{
    #[inline(always)]
    fn into(self) -> [T; 2]{
        [self.0, self.1]
    }
}

impl<T: Copy> From<[T; 2]> for Vector2<T>{
    #[inline(always)]
    fn from(array: [T; 2]) -> Self{
        Vector2(array[0], array[1])
    }
}

impl<T> Into<(T, T)> for Vector2<T>{
    #[inline(always)]
    fn into(self) -> (T, T){
        (self.0, self.1)
    }
}

impl<T> From<(T, T)> for Vector2<T>{
    #[inline(always)]
    fn from(tuple: (T, T)) -> Self{
        Vector2(tuple.0, tuple.1)
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::{cmp, fmt};

use index::{ByteIndex, Index};

/// A region of code in a source file
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Ord, PartialOrd)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(HeapSizeOf))]
pub struct Span<I> {
    start: I,
    end: I,
}

impl<I: Ord> Span<I> {
    /// Create a new span
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.start(), ByteIndex(3));
    /// assert_eq!(span.end(), ByteIndex(6));
    /// ```
    ///
    /// `start` and `end` are reordered to maintain the invariant that `start <= end`
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(6), ByteIndex(3));
    /// assert_eq!(span.start(), ByteIndex(3));
    /// assert_eq!(span.end(), ByteIndex(6));
    /// ```
    pub fn new(start: I, end: I) -> Span<I> {
        if start <= end {
            Span { start, end }
        } else {
            Span {
                start: end,
                end: start,
            }
        }
    }

    pub fn map<F, J>(self, mut f: F) -> Span<J>
    where
        F: FnMut(I) -> J,
        J: Ord,
    {
        Span::new(f(self.start), f(self.end))
    }
}

impl<I> Span<I> {
    /// Get the start index
    pub fn start(self) -> I {
        self.start
    }

    /// Get the end index
    pub fn end(self) -> I {
        self.end
    }
}

impl<I: Index> Span<I> {
    /// Makes a span from offsets relative to the start of this span.
    pub fn subspan(&self, begin: I::Offset, end: I::Offset) -> Span<I> {
        assert!(end >= begin);
        assert!(self.start() + end <= self.end());
        Span {
            start: self.start() + begin,
            end: self.start() + end,
        }
    }

    /// Create a new span from a byte start and an offset
    pub fn from_offset(start: I, off: I::Offset) -> Span<I> {
        Span::new(start, start + off)
    }

    /// Return a new span with the low byte position replaced with the supplied byte position
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.with_start(ByteIndex(2)), Span::new(ByteIndex(2), ByteIndex(6)));
    /// assert_eq!(span.with_start(ByteIndex(5)), Span::new(ByteIndex(5), ByteIndex(6)));
    /// assert_eq!(span.with_start(ByteIndex(7)), Span::new(ByteIndex(6), ByteIndex(7)));
    /// ```
    pub fn with_start(self, start: I) -> Span<I> {
        Span::new(start, self.end())
    }

    /// Return a new span with the high byte position replaced with the supplied byte position
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.with_end(ByteIndex(7)), Span::new(ByteIndex(3), ByteIndex(7)));
    /// assert_eq!(span.with_end(ByteIndex(5)), Span::new(ByteIndex(3), ByteIndex(5)));
    /// assert_eq!(span.with_end(ByteIndex(2)), Span::new(ByteIndex(2), ByteIndex(3)));
    /// ```
    pub fn with_end(self, end: I) -> Span<I> {
        Span::new(self.start(), end)
    }

    /// Return true if `self` fully encloses `other`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.contains(a), true);
    /// assert_eq!(a.contains(Span::new(ByteIndex(6), ByteIndex(7))), true);
    /// assert_eq!(a.contains(Span::new(ByteIndex(6), ByteIndex(10))), false);
    /// assert_eq!(a.contains(Span::new(ByteIndex(3), ByteIndex(6))), false);
    /// ```
    pub fn contains(self, other: Span<I>) -> bool {
        self.start() <= other.start() && other.end() <= self.end()
    }

    /// Return `Equal` if `self` contains `pos`, otherwise it returns `Less` if `pos` is before
    /// `start` or `Greater` if `pos` is after or at `end`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    /// use std::cmp::Ordering::*;
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.containment(ByteIndex(4)), Less);
    /// assert_eq!(a.containment(ByteIndex(5)), Equal);
    /// assert_eq!(a.containment(ByteIndex(6)), Equal);
    /// assert_eq!(a.containment(ByteIndex(8)), Equal);
    /// assert_eq!(a.containment(ByteIndex(9)), Greater);
    /// ```
    pub fn containment(self, pos: I) -> Ordering {
        use std::cmp::Ordering::*;

        match (pos.cmp(&self.start), pos.cmp(&self.end)) {
            (Equal, _) | (_, Equal) | (Greater, Less) => Equal,
            (Less, _) => Less,
            (_, Greater) => Greater,
        }
    }

    /// Return `Equal` if `self` contains `pos`, otherwise it returns `Less` if `pos` is before
    /// `start` or `Greater` if `pos` is *strictly* after `end`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    /// use std::cmp::Ordering::*;
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.containment_exclusive(ByteIndex(4)), Less);
    /// assert_eq!(a.containment_exclusive(ByteIndex(5)), Equal);
    /// assert_eq!(a.containment_exclusive(ByteIndex(6)), Equal);
    /// assert_eq!(a.containment_exclusive(ByteIndex(8)), Greater);
    /// assert_eq!(a.containment_exclusive(ByteIndex(9)), Greater);
    /// ```
    pub fn containment_exclusive(self, pos: I) -> Ordering {
        if self.end == pos {
            Ordering::Greater
        } else {
            self.containment(pos)
        }
    }

    /// Return a `Span` that would enclose both `self` and `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns  ~~~~~~~~~~~~~~~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.to(b), Span::new(ByteIndex(2), ByteIndex(14)));
    /// ```
    pub fn to(self, end: Span<I>) -> Span<I> {
        Span::new(
            cmp::min(self.start(), end.start()),
            cmp::max(self.end(), end.end()),
        )
    }

    /// Return a `Span` between the end of `self` to the beginning of `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns         ~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.between(b), Span::new(ByteIndex(5), ByteIndex(10)));
    /// ```
    pub fn between(self, end: Span<I>) -> Span<I> {
        Span::new(self.end(), end.start())
    }

    /// Return a `Span` between the beginning of `self` to the beginning of `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns  ~~~~~~~~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.until(b), Span::new(ByteIndex(2), ByteIndex(10)));
    /// ```
    pub fn until(self, end: Span<I>) -> Span<I> {
        Span::new(self.start(), end.start())
    }
}

impl<I: fmt::Display> fmt::Display for Span<I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.start.fmt(f)?;
        write!(f, "..")?;
        self.end.fmt(f)?;
        Ok(())
    }
}

/// A span of byte indices
pub type ByteSpan = Span<ByteIndex>;
<commit_msg>feat: Add new_unchecked as a const function<commit_after>use std::cmp::Ordering;
use std::{cmp, fmt};

use index::{ByteIndex, Index};

/// A region of code in a source file
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Ord, PartialOrd)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(HeapSizeOf))]
pub struct Span<I> {
    start: I,
    end: I,
}

impl<I: Ord> Span<I> {
    /// Create a new span
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.start(), ByteIndex(3));
    /// assert_eq!(span.end(), ByteIndex(6));
    /// ```
    ///
    /// `start` and `end` are reordered to maintain the invariant that `start <= end`
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(6), ByteIndex(3));
    /// assert_eq!(span.start(), ByteIndex(3));
    /// assert_eq!(span.end(), ByteIndex(6));
    /// ```
    pub fn new(start: I, end: I) -> Span<I> {
        if start <= end {
            Span { start, end }
        } else {
            Span {
                start: end,
                end: start,
            }
        }
    }

    pub fn map<F, J>(self, mut f: F) -> Span<J>
    where
        F: FnMut(I) -> J,
        J: Ord,
    {
        Span::new(f(self.start), f(self.end))
    }
}

impl<I> Span<I> {
    /// Create a span like `new` but does not check that `start <= end`
    pub const fn new_unchecked(start: I, end: I) -> Span<I> {
        Span { start, end }
    }
}

impl<I> Span<I> {
    /// Get the start index
    pub fn start(self) -> I {
        self.start
    }

    /// Get the end index
    pub fn end(self) -> I {
        self.end
    }
}

impl<I: Index> Span<I> {
    /// Makes a span from offsets relative to the start of this span.
    pub fn subspan(&self, begin: I::Offset, end: I::Offset) -> Span<I> {
        assert!(end >= begin);
        assert!(self.start() + end <= self.end());
        Span {
            start: self.start() + begin,
            end: self.start() + end,
        }
    }

    /// Create a new span from a byte start and an offset
    pub fn from_offset(start: I, off: I::Offset) -> Span<I> {
        Span::new(start, start + off)
    }

    /// Return a new span with the low byte position replaced with the supplied byte position
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.with_start(ByteIndex(2)), Span::new(ByteIndex(2), ByteIndex(6)));
    /// assert_eq!(span.with_start(ByteIndex(5)), Span::new(ByteIndex(5), ByteIndex(6)));
    /// assert_eq!(span.with_start(ByteIndex(7)), Span::new(ByteIndex(6), ByteIndex(7)));
    /// ```
    pub fn with_start(self, start: I) -> Span<I> {
        Span::new(start, self.end())
    }

    /// Return a new span with the high byte position replaced with the supplied byte position
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(ByteIndex(3), ByteIndex(6));
    /// assert_eq!(span.with_end(ByteIndex(7)), Span::new(ByteIndex(3), ByteIndex(7)));
    /// assert_eq!(span.with_end(ByteIndex(5)), Span::new(ByteIndex(3), ByteIndex(5)));
    /// assert_eq!(span.with_end(ByteIndex(2)), Span::new(ByteIndex(2), ByteIndex(3)));
    /// ```
    pub fn with_end(self, end: I) -> Span<I> {
        Span::new(self.start(), end)
    }

    /// Return true if `self` fully encloses `other`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.contains(a), true);
    /// assert_eq!(a.contains(Span::new(ByteIndex(6), ByteIndex(7))), true);
    /// assert_eq!(a.contains(Span::new(ByteIndex(6), ByteIndex(10))), false);
    /// assert_eq!(a.contains(Span::new(ByteIndex(3), ByteIndex(6))), false);
    /// ```
    pub fn contains(self, other: Span<I>) -> bool {
        self.start() <= other.start() && other.end() <= self.end()
    }

    /// Return `Equal` if `self` contains `pos`, otherwise it returns `Less` if `pos` is before
    /// `start` or `Greater` if `pos` is after or at `end`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    /// use std::cmp::Ordering::*;
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.containment(ByteIndex(4)), Less);
    /// assert_eq!(a.containment(ByteIndex(5)), Equal);
    /// assert_eq!(a.containment(ByteIndex(6)), Equal);
    /// assert_eq!(a.containment(ByteIndex(8)), Equal);
    /// assert_eq!(a.containment(ByteIndex(9)), Greater);
    /// ```
    pub fn containment(self, pos: I) -> Ordering {
        use std::cmp::Ordering::*;

        match (pos.cmp(&self.start), pos.cmp(&self.end)) {
            (Equal, _) | (_, Equal) | (Greater, Less) => Equal,
            (Less, _) => Less,
            (_, Greater) => Greater,
        }
    }

    /// Return `Equal` if `self` contains `pos`, otherwise it returns `Less` if `pos` is before
    /// `start` or `Greater` if `pos` is *strictly* after `end`.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    /// use std::cmp::Ordering::*;
    ///
    /// let a = Span::new(ByteIndex(5), ByteIndex(8));
    ///
    /// assert_eq!(a.containment_exclusive(ByteIndex(4)), Less);
    /// assert_eq!(a.containment_exclusive(ByteIndex(5)), Equal);
    /// assert_eq!(a.containment_exclusive(ByteIndex(6)), Equal);
    /// assert_eq!(a.containment_exclusive(ByteIndex(8)), Greater);
    /// assert_eq!(a.containment_exclusive(ByteIndex(9)), Greater);
    /// ```
    pub fn containment_exclusive(self, pos: I) -> Ordering {
        if self.end == pos {
            Ordering::Greater
        } else {
            self.containment(pos)
        }
    }

    /// Return a `Span` that would enclose both `self` and `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns  ~~~~~~~~~~~~~~~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.to(b), Span::new(ByteIndex(2), ByteIndex(14)));
    /// ```
    pub fn to(self, end: Span<I>) -> Span<I> {
        Span::new(
            cmp::min(self.start(), end.start()),
            cmp::max(self.end(), end.end()),
        )
    }

    /// Return a `Span` between the end of `self` to the beginning of `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns         ~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.between(b), Span::new(ByteIndex(5), ByteIndex(10)));
    /// ```
    pub fn between(self, end: Span<I>) -> Span<I> {
        Span::new(self.end(), end.start())
    }

    /// Return a `Span` between the beginning of `self` to the beginning of `end`.
    ///
    /// ```plain
    /// self     ~~~~~~~
    /// end                     ~~~~~~~~
    /// returns  ~~~~~~~~~~~~~~~~
    /// ```
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let a = Span::new(ByteIndex(2), ByteIndex(5));
    /// let b = Span::new(ByteIndex(10), ByteIndex(14));
    ///
    /// assert_eq!(a.until(b), Span::new(ByteIndex(2), ByteIndex(10)));
    /// ```
    pub fn until(self, end: Span<I>) -> Span<I> {
        Span::new(self.start(), end.start())
    }
}

impl<I: fmt::Display> fmt::Display for Span<I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.start.fmt(f)?;
        write!(f, "..")?;
        self.end.fmt(f)?;
        Ok(())
    }
}

/// A span of byte indices
pub type ByteSpan = Span<ByteIndex>;
<|endoftext|>


<commit_before>// Options
// Space before /?
// Quote style

#[cfg(test)]
mod test {
    use std::io::{IoResult,MemWriter};

    use super::super::{Document,Element};

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    fn format_document<W : Writer>(doc: &Document, writer: &mut W) -> IoResult<()> {
        try!(writer.write_str("<?xml version='1.0'?>"));
        let e = doc.root().children()[0].element().expect("not an element?");
        write!(writer, "<{}/>", e.name())
    }

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn format_an_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }
}
<commit_msg>Write a single self-closed element with attributes<commit_after>// Options
// Space before /
// Quote style
// Ordering of attributes

#[cfg(test)]
mod test {
    use std::io::{IoResult,MemWriter};

    use super::super::{Document,Element};

    macro_rules! assert_str_eq(
        ($l:expr, $r:expr) => (assert_eq!($l.as_slice(), $r.as_slice()));
    )

    fn format_document<W : Writer>(doc: &Document, writer: &mut W) -> IoResult<()> {
        try!(writer.write_str("<?xml version='1.0'?>"));
        let e = doc.root().children()[0].element().expect("not an element?");
        try!(write!(writer, "<{}", e.name()));
        for attr in e.attributes().iter() {
            try!(write!(writer, " {}='{}'", attr.name(), attr.value()));
        }
        writer.write_str("/>")
    }

    fn format_xml(doc: &Document) -> String {
        let mut w = MemWriter::new();
        format_document(doc, &mut w).ok().expect("Not formatted");
        String::from_utf8(w.unwrap()).ok().expect("Not a string")
    }

    #[test]
    fn top_element() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello/>");
    }

    #[test]
    fn element_with_attributes() {
        let d = Document::new();
        let e = d.new_element("hello".to_string());
        e.set_attribute("a".to_string(), "b".to_string());
        d.root().append_child(e);

        let xml = format_xml(&d);
        assert_str_eq!(xml, "<?xml version='1.0'?><hello a='b'/>");
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate rustc_serialize;

use self::chrono::{DateTime, UTC};
use rustc_serialize::json::{ToJson, Json};
use std::collections::BTreeMap;

#[derive(Debug, Clone)]
pub struct Period {
  pub started_at: chrono::DateTime<UTC>,
  pub finished_at: chrono::DateTime<UTC>
}

#[derive(Debug, Clone, RustcDecodable)]
pub struct Request {
  pub id: String,
  pub command: String,
  pub cwd: String
}

#[derive(Debug, Clone)]
pub struct Response {
  pub status: i32,
  pub stderr: String,
  pub stdout: String,
  pub period: Period
}

#[derive(Debug, Clone)]
pub struct Item {
  pub request: Request,
  pub response: Response
}

impl Item {
  pub fn to_record (&self) -> Record {
    Record {
      id: self.request.id.clone(),
      command: self.request.command.clone(),
      cwd: self.request.cwd.clone(),
      status: self.response.status.clone(),
      stderr: self.response.stderr.clone(),
      stdout: self.response.stdout.clone(),
      started_at: self.response.period.started_at.clone(),
      finished_at: self.response.period.finished_at.clone()
    }
  }
}

#[derive(Debug, Clone)]
pub struct Record {
  pub id: String,
  pub command: String,
  pub cwd: String,
  pub status: i32,
  pub stderr: String,
  pub stdout: String,
  pub started_at: chrono::DateTime<UTC>,
  pub finished_at: chrono::DateTime<UTC>
}

impl ToJson for Record {

  fn to_json(&self) -> Json {
    let mut data = BTreeMap::new();
    data.insert("id".to_string(), self.id.to_json());
    data.insert("command".to_string(), self.command.to_json());
    data.insert("cwd".to_string(), self.cwd.to_json());
    data.insert("status".to_string(), self.status.to_json());
    data.insert("stderr".to_string(), self.stderr.to_json());
    data.insert("stdout".to_string(), self.stdout.to_json());
    data.insert("started_at".to_string(), self.started_at.to_rfc3339().to_json());
    data.insert("finished_at".to_string(), self.finished_at.to_rfc3339().to_json());
    Json::Object(data)
  }

}<commit_msg>use camelCase for responses<commit_after>extern crate chrono;
extern crate rustc_serialize;

use self::chrono::{DateTime, UTC};
use rustc_serialize::json::{ToJson, Json};
use std::collections::BTreeMap;

#[derive(Debug, Clone)]
pub struct Period {
  pub started_at: chrono::DateTime<UTC>,
  pub finished_at: chrono::DateTime<UTC>
}

#[derive(Debug, Clone, RustcDecodable)]
pub struct Request {
  pub id: String,
  pub command: String,
  pub cwd: String
}

#[derive(Debug, Clone)]
pub struct Response {
  pub status: i32,
  pub stderr: String,
  pub stdout: String,
  pub period: Period
}

#[derive(Debug, Clone)]
pub struct Item {
  pub request: Request,
  pub response: Response
}

impl Item {
  pub fn to_record (&self) -> Record {
    Record {
      id: self.request.id.clone(),
      command: self.request.command.clone(),
      cwd: self.request.cwd.clone(),
      status: self.response.status.clone(),
      stderr: self.response.stderr.clone(),
      stdout: self.response.stdout.clone(),
      started_at: self.response.period.started_at.clone(),
      finished_at: self.response.period.finished_at.clone()
    }
  }
}

#[derive(Debug, Clone)]
pub struct Record {
  pub id: String,
  pub command: String,
  pub cwd: String,
  pub status: i32,
  pub stderr: String,
  pub stdout: String,
  pub started_at: chrono::DateTime<UTC>,
  pub finished_at: chrono::DateTime<UTC>
}

impl ToJson for Record {

  fn to_json(&self) -> Json {
    let mut data = BTreeMap::new();
    data.insert("id".to_string(), self.id.to_json());
    data.insert("command".to_string(), self.command.to_json());
    data.insert("cwd".to_string(), self.cwd.to_json());
    data.insert("status".to_string(), self.status.to_json());
    data.insert("stderr".to_string(), self.stderr.to_json());
    data.insert("stdout".to_string(), self.stdout.to_json());
    data.insert("startedAt".to_string(), self.started_at.to_rfc3339().to_json());
    data.insert("finishedAt".to_string(), self.finished_at.to_rfc3339().to_json());
    Json::Object(data)
  }

}<|endoftext|>


<commit_before>use crate::check::method::MethodCallee;
use crate::check::{FnCtxt, PlaceOp};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::autoderef::Autoderef;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    /// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
    pub(super) fn lookup_derefing(
        &self,
        expr: &hir::Expr<'_>,
        oprnd_expr: &'tcx hir::Expr<'tcx>,
        oprnd_ty: Ty<'tcx>,
    ) -> Option<Ty<'tcx>> {
        if let Some(mt) = oprnd_ty.builtin_deref(true) {
            return Some(mt.ty);
        }

        let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
        let method = self.register_infer_ok_obligations(ok);
        if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind {
            self.apply_adjustments(
                oprnd_expr,
                vec![Adjustment {
                    kind: Adjust::Borrow(AutoBorrow::Ref(region, AutoBorrowMutability::Not)),
                    target: method.sig.inputs()[0],
                }],
            );
        } else {
            span_bug!(expr.span, "input to deref is not a ref?");
        }
        let ty = self.make_overloaded_place_return_type(method).ty;
        self.write_method_call(expr.hir_id, method);
        Some(ty)
    }

    /// Type-check `*base_expr[index_expr]` with `base_expr` and `index_expr` type-checked already.
    pub(super) fn lookup_indexing(
        &self,
        expr: &hir::Expr<'_>,
        base_expr: &'tcx hir::Expr<'tcx>,
        base_ty: Ty<'tcx>,
        idx_ty: Ty<'tcx>,
    ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
        // FIXME(#18741) -- this is almost but not quite the same as the
        // autoderef that normal method probing does. They could likely be
        // consolidated.

        let mut autoderef = self.autoderef(base_expr.span, base_ty);
        let mut result = None;
        while result.is_none() && autoderef.next().is_some() {
            result = self.try_index_step(expr, base_expr, &autoderef, idx_ty);
        }
        self.register_predicates(autoderef.into_obligations());
        result
    }

    /// To type-check `base_expr[index_expr]`, we progressively autoderef
    /// (and otherwise adjust) `base_expr`, looking for a type which either
    /// supports builtin indexing or overloaded indexing.
    /// This loop implements one step in that search; the autoderef loop
    /// is implemented by `lookup_indexing`.
    fn try_index_step(
        &self,
        expr: &hir::Expr<'_>,
        base_expr: &hir::Expr<'_>,
        autoderef: &Autoderef<'a, 'tcx>,
        index_ty: Ty<'tcx>,
    ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
        let adjusted_ty =
            self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
        debug!(
            "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
             index_ty={:?})",
            expr, base_expr, adjusted_ty, index_ty
        );

        for &unsize in &[false, true] {
            let mut self_ty = adjusted_ty;
            if unsize {
                // We only unsize arrays here.
                if let ty::Array(element_ty, _) = adjusted_ty.kind {
                    self_ty = self.tcx.mk_slice(element_ty);
                } else {
                    continue;
                }
            }

            // If some lookup succeeds, write callee into table and extract index/element
            // type from the method signature.
            // If some lookup succeeded, install method in table
            let input_ty = self.next_ty_var(TypeVariableOrigin {
                kind: TypeVariableOriginKind::AutoDeref,
                span: base_expr.span,
            });
            let method =
                self.try_overloaded_place_op(expr.span, self_ty, &[input_ty], PlaceOp::Index);

            let result = method.map(|ok| {
                debug!("try_index_step: success, using overloaded indexing");
                let method = self.register_infer_ok_obligations(ok);

                let mut adjustments = self.adjust_steps(autoderef);
                if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind {
                    adjustments.push(Adjustment {
                        kind: Adjust::Borrow(AutoBorrow::Ref(region, AutoBorrowMutability::Not)),
                        target: self.tcx.mk_ref(
                            region,
                            ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: adjusted_ty },
                        ),
                    });
                } else {
                    span_bug!(expr.span, "input to index is not a ref?");
                }
                if unsize {
                    adjustments.push(Adjustment {
                        kind: Adjust::Pointer(PointerCast::Unsize),
                        target: method.sig.inputs()[0],
                    });
                }
                self.apply_adjustments(base_expr, adjustments);

                self.write_method_call(expr.hir_id, method);
                (input_ty, self.make_overloaded_place_return_type(method).ty)
            });
            if result.is_some() {
                return result;
            }
        }

        None
    }

    /// Try to resolve an overloaded place op. We only deal with the immutable
    /// variant here (Deref/Index). In some contexts we would need the mutable
    /// variant (DerefMut/IndexMut); those would be later converted by
    /// `convert_place_derefs_to_mutable`.
    pub(super) fn try_overloaded_place_op(
        &self,
        span: Span,
        base_ty: Ty<'tcx>,
        arg_tys: &[Ty<'tcx>],
        op: PlaceOp,
    ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);

        let (imm_tr, imm_op) = match op {
            PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
            PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
        };
        imm_tr.and_then(|trait_did| {
            self.lookup_method_in_trait(
                span,
                Ident::with_dummy_span(imm_op),
                trait_did,
                base_ty,
                Some(arg_tys),
            )
        })
    }

    fn try_mutable_overloaded_place_op(
        &self,
        span: Span,
        base_ty: Ty<'tcx>,
        arg_tys: &[Ty<'tcx>],
        op: PlaceOp,
    ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);

        let (mut_tr, mut_op) = match op {
            PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
            PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
        };
        mut_tr.and_then(|trait_did| {
            self.lookup_method_in_trait(
                span,
                Ident::with_dummy_span(mut_op),
                trait_did,
                base_ty,
                Some(arg_tys),
            )
        })
    }

    /// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index`
    /// into `DerefMut` and `IndexMut` respectively.
    ///
    /// This is a second pass of typechecking derefs/indices. We need this we do not
    /// always know whether a place needs to be mutable or not in the first pass.
    /// This happens whether there is an implicit mutable reborrow, e.g. when the type
    /// is used as the receiver of a method call.
    pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
        // Gather up expressions we want to munge.
        let mut exprs = vec![expr];

        loop {
            match exprs.last().unwrap().kind {
                hir::ExprKind::Field(ref expr, _)
                | hir::ExprKind::Index(ref expr, _)
                | hir::ExprKind::Unary(hir::UnOp::UnDeref, ref expr) => exprs.push(&expr),
                _ => break,
            }
        }

        debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);

        // Fix up autoderefs and derefs.
        for (i, &expr) in exprs.iter().rev().enumerate() {
            debug!("convert_place_derefs_to_mutable: i={} expr={:?}", i, expr);

            // Fix up the autoderefs. Autorefs can only occur immediately preceding
            // overloaded place ops, and will be fixed by them in order to get
            // the correct region.
            let mut source = self.node_ty(expr.hir_id);
            // Do not mutate adjustments in place, but rather take them,
            // and replace them after mutating them, to avoid having the
            // typeck results borrowed during (`deref_mut`) method resolution.
            let previous_adjustments =
                self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
            if let Some(mut adjustments) = previous_adjustments {
                for adjustment in &mut adjustments {
                    if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
                        if let Some(ok) = self.try_mutable_overloaded_place_op(
                            expr.span,
                            source,
                            &[],
                            PlaceOp::Deref,
                        ) {
                            let method = self.register_infer_ok_obligations(ok);
                            if let ty::Ref(region, _, mutbl) = method.sig.output().kind {
                                *deref = OverloadedDeref { region, mutbl };
                            }
                        }
                    }
                    source = adjustment.target;
                }
                self.typeck_results.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments);
            }

            match expr.kind {
                hir::ExprKind::Index(ref base_expr, ref index_expr) => {
                    // We need to get the final type in case dereferences were needed for the trait
                    // to apply (#72002).
                    let index_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(index_expr);
                    self.convert_place_op_to_mutable(
                        PlaceOp::Index,
                        expr,
                        base_expr,
                        &[index_expr_ty],
                    );
                }
                hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => {
                    self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]);
                }
                _ => {}
            }
        }
    }

    fn convert_place_op_to_mutable(
        &self,
        op: PlaceOp,
        expr: &hir::Expr<'_>,
        base_expr: &hir::Expr<'_>,
        arg_tys: &[Ty<'tcx>],
    ) {
        debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys);
        if !self.typeck_results.borrow().is_method_call(expr) {
            debug!("convert_place_op_to_mutable - builtin, nothing to do");
            return;
        }

        // Need to deref because overloaded place ops take self by-reference.
        let base_ty = self
            .typeck_results
            .borrow()
            .expr_ty_adjusted(base_expr)
            .builtin_deref(false)
            .expect("place op takes something that is not a ref")
            .ty;

        let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op);
        let method = match method {
            Some(ok) => self.register_infer_ok_obligations(ok),
            // Couldn't find the mutable variant of the place op, keep the
            // current, immutable version.
            None => return,
        };
        debug!("convert_place_op_to_mutable: method={:?}", method);
        self.write_method_call(expr.hir_id, method);

        let region = if let ty::Ref(r, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind {
            r
        } else {
            span_bug!(expr.span, "input to mutable place op is not a mut ref?");
        };

        // Convert the autoref in the base expr to mutable with the correct
        // region and mutability.
        let base_expr_ty = self.node_ty(base_expr.hir_id);
        if let Some(adjustments) =
            self.typeck_results.borrow_mut().adjustments_mut().get_mut(base_expr.hir_id)
        {
            let mut source = base_expr_ty;
            for adjustment in &mut adjustments[..] {
                if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {
                    debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment);
                    let mutbl = AutoBorrowMutability::Mut {
                        // Deref/indexing can be desugared to a method call,
                        // so maybe we could use two-phase here.
                        // See the documentation of AllowTwoPhase for why that's
                        // not the case today.
                        allow_two_phase_borrow: AllowTwoPhase::No,
                    };
                    adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl));
                    adjustment.target =
                        self.tcx.mk_ref(region, ty::TypeAndMut { ty: source, mutbl: mutbl.into() });
                }
                source = adjustment.target;
            }

            // If we have an autoref followed by unsizing at the end, fix the unsize target.
            if let [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] =
                adjustments[..]
            {
                *target = method.sig.inputs()[0];
            }
        }
    }
}
<commit_msg>fix clippy::while_let_loop: use while let{} instead of loop { if ... break; }<commit_after>use crate::check::method::MethodCallee;
use crate::check::{FnCtxt, PlaceOp};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::autoderef::Autoderef;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    /// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
    pub(super) fn lookup_derefing(
        &self,
        expr: &hir::Expr<'_>,
        oprnd_expr: &'tcx hir::Expr<'tcx>,
        oprnd_ty: Ty<'tcx>,
    ) -> Option<Ty<'tcx>> {
        if let Some(mt) = oprnd_ty.builtin_deref(true) {
            return Some(mt.ty);
        }

        let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
        let method = self.register_infer_ok_obligations(ok);
        if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind {
            self.apply_adjustments(
                oprnd_expr,
                vec![Adjustment {
                    kind: Adjust::Borrow(AutoBorrow::Ref(region, AutoBorrowMutability::Not)),
                    target: method.sig.inputs()[0],
                }],
            );
        } else {
            span_bug!(expr.span, "input to deref is not a ref?");
        }
        let ty = self.make_overloaded_place_return_type(method).ty;
        self.write_method_call(expr.hir_id, method);
        Some(ty)
    }

    /// Type-check `*base_expr[index_expr]` with `base_expr` and `index_expr` type-checked already.
    pub(super) fn lookup_indexing(
        &self,
        expr: &hir::Expr<'_>,
        base_expr: &'tcx hir::Expr<'tcx>,
        base_ty: Ty<'tcx>,
        idx_ty: Ty<'tcx>,
    ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
        // FIXME(#18741) -- this is almost but not quite the same as the
        // autoderef that normal method probing does. They could likely be
        // consolidated.

        let mut autoderef = self.autoderef(base_expr.span, base_ty);
        let mut result = None;
        while result.is_none() && autoderef.next().is_some() {
            result = self.try_index_step(expr, base_expr, &autoderef, idx_ty);
        }
        self.register_predicates(autoderef.into_obligations());
        result
    }

    /// To type-check `base_expr[index_expr]`, we progressively autoderef
    /// (and otherwise adjust) `base_expr`, looking for a type which either
    /// supports builtin indexing or overloaded indexing.
    /// This loop implements one step in that search; the autoderef loop
    /// is implemented by `lookup_indexing`.
    fn try_index_step(
        &self,
        expr: &hir::Expr<'_>,
        base_expr: &hir::Expr<'_>,
        autoderef: &Autoderef<'a, 'tcx>,
        index_ty: Ty<'tcx>,
    ) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
        let adjusted_ty =
            self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
        debug!(
            "try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
             index_ty={:?})",
            expr, base_expr, adjusted_ty, index_ty
        );

        for &unsize in &[false, true] {
            let mut self_ty = adjusted_ty;
            if unsize {
                // We only unsize arrays here.
                if let ty::Array(element_ty, _) = adjusted_ty.kind {
                    self_ty = self.tcx.mk_slice(element_ty);
                } else {
                    continue;
                }
            }

            // If some lookup succeeds, write callee into table and extract index/element
            // type from the method signature.
            // If some lookup succeeded, install method in table
            let input_ty = self.next_ty_var(TypeVariableOrigin {
                kind: TypeVariableOriginKind::AutoDeref,
                span: base_expr.span,
            });
            let method =
                self.try_overloaded_place_op(expr.span, self_ty, &[input_ty], PlaceOp::Index);

            let result = method.map(|ok| {
                debug!("try_index_step: success, using overloaded indexing");
                let method = self.register_infer_ok_obligations(ok);

                let mut adjustments = self.adjust_steps(autoderef);
                if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind {
                    adjustments.push(Adjustment {
                        kind: Adjust::Borrow(AutoBorrow::Ref(region, AutoBorrowMutability::Not)),
                        target: self.tcx.mk_ref(
                            region,
                            ty::TypeAndMut { mutbl: hir::Mutability::Not, ty: adjusted_ty },
                        ),
                    });
                } else {
                    span_bug!(expr.span, "input to index is not a ref?");
                }
                if unsize {
                    adjustments.push(Adjustment {
                        kind: Adjust::Pointer(PointerCast::Unsize),
                        target: method.sig.inputs()[0],
                    });
                }
                self.apply_adjustments(base_expr, adjustments);

                self.write_method_call(expr.hir_id, method);
                (input_ty, self.make_overloaded_place_return_type(method).ty)
            });
            if result.is_some() {
                return result;
            }
        }

        None
    }

    /// Try to resolve an overloaded place op. We only deal with the immutable
    /// variant here (Deref/Index). In some contexts we would need the mutable
    /// variant (DerefMut/IndexMut); those would be later converted by
    /// `convert_place_derefs_to_mutable`.
    pub(super) fn try_overloaded_place_op(
        &self,
        span: Span,
        base_ty: Ty<'tcx>,
        arg_tys: &[Ty<'tcx>],
        op: PlaceOp,
    ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);

        let (imm_tr, imm_op) = match op {
            PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
            PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
        };
        imm_tr.and_then(|trait_did| {
            self.lookup_method_in_trait(
                span,
                Ident::with_dummy_span(imm_op),
                trait_did,
                base_ty,
                Some(arg_tys),
            )
        })
    }

    fn try_mutable_overloaded_place_op(
        &self,
        span: Span,
        base_ty: Ty<'tcx>,
        arg_tys: &[Ty<'tcx>],
        op: PlaceOp,
    ) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
        debug!("try_mutable_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);

        let (mut_tr, mut_op) = match op {
            PlaceOp::Deref => (self.tcx.lang_items().deref_mut_trait(), sym::deref_mut),
            PlaceOp::Index => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
        };
        mut_tr.and_then(|trait_did| {
            self.lookup_method_in_trait(
                span,
                Ident::with_dummy_span(mut_op),
                trait_did,
                base_ty,
                Some(arg_tys),
            )
        })
    }

    /// Convert auto-derefs, indices, etc of an expression from `Deref` and `Index`
    /// into `DerefMut` and `IndexMut` respectively.
    ///
    /// This is a second pass of typechecking derefs/indices. We need this we do not
    /// always know whether a place needs to be mutable or not in the first pass.
    /// This happens whether there is an implicit mutable reborrow, e.g. when the type
    /// is used as the receiver of a method call.
    pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
        // Gather up expressions we want to munge.
        let mut exprs = vec![expr];

        while let hir::ExprKind::Field(ref expr, _)
        | hir::ExprKind::Index(ref expr, _)
        | hir::ExprKind::Unary(hir::UnOp::UnDeref, ref expr) = exprs.last().unwrap().kind
        {
            exprs.push(&expr);
        }

        debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);

        // Fix up autoderefs and derefs.
        for (i, &expr) in exprs.iter().rev().enumerate() {
            debug!("convert_place_derefs_to_mutable: i={} expr={:?}", i, expr);

            // Fix up the autoderefs. Autorefs can only occur immediately preceding
            // overloaded place ops, and will be fixed by them in order to get
            // the correct region.
            let mut source = self.node_ty(expr.hir_id);
            // Do not mutate adjustments in place, but rather take them,
            // and replace them after mutating them, to avoid having the
            // typeck results borrowed during (`deref_mut`) method resolution.
            let previous_adjustments =
                self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
            if let Some(mut adjustments) = previous_adjustments {
                for adjustment in &mut adjustments {
                    if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
                        if let Some(ok) = self.try_mutable_overloaded_place_op(
                            expr.span,
                            source,
                            &[],
                            PlaceOp::Deref,
                        ) {
                            let method = self.register_infer_ok_obligations(ok);
                            if let ty::Ref(region, _, mutbl) = method.sig.output().kind {
                                *deref = OverloadedDeref { region, mutbl };
                            }
                        }
                    }
                    source = adjustment.target;
                }
                self.typeck_results.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments);
            }

            match expr.kind {
                hir::ExprKind::Index(ref base_expr, ref index_expr) => {
                    // We need to get the final type in case dereferences were needed for the trait
                    // to apply (#72002).
                    let index_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(index_expr);
                    self.convert_place_op_to_mutable(
                        PlaceOp::Index,
                        expr,
                        base_expr,
                        &[index_expr_ty],
                    );
                }
                hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => {
                    self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]);
                }
                _ => {}
            }
        }
    }

    fn convert_place_op_to_mutable(
        &self,
        op: PlaceOp,
        expr: &hir::Expr<'_>,
        base_expr: &hir::Expr<'_>,
        arg_tys: &[Ty<'tcx>],
    ) {
        debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys);
        if !self.typeck_results.borrow().is_method_call(expr) {
            debug!("convert_place_op_to_mutable - builtin, nothing to do");
            return;
        }

        // Need to deref because overloaded place ops take self by-reference.
        let base_ty = self
            .typeck_results
            .borrow()
            .expr_ty_adjusted(base_expr)
            .builtin_deref(false)
            .expect("place op takes something that is not a ref")
            .ty;

        let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op);
        let method = match method {
            Some(ok) => self.register_infer_ok_obligations(ok),
            // Couldn't find the mutable variant of the place op, keep the
            // current, immutable version.
            None => return,
        };
        debug!("convert_place_op_to_mutable: method={:?}", method);
        self.write_method_call(expr.hir_id, method);

        let region = if let ty::Ref(r, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind {
            r
        } else {
            span_bug!(expr.span, "input to mutable place op is not a mut ref?");
        };

        // Convert the autoref in the base expr to mutable with the correct
        // region and mutability.
        let base_expr_ty = self.node_ty(base_expr.hir_id);
        if let Some(adjustments) =
            self.typeck_results.borrow_mut().adjustments_mut().get_mut(base_expr.hir_id)
        {
            let mut source = base_expr_ty;
            for adjustment in &mut adjustments[..] {
                if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {
                    debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment);
                    let mutbl = AutoBorrowMutability::Mut {
                        // Deref/indexing can be desugared to a method call,
                        // so maybe we could use two-phase here.
                        // See the documentation of AllowTwoPhase for why that's
                        // not the case today.
                        allow_two_phase_borrow: AllowTwoPhase::No,
                    };
                    adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl));
                    adjustment.target =
                        self.tcx.mk_ref(region, ty::TypeAndMut { ty: source, mutbl: mutbl.into() });
                }
                source = adjustment.target;
            }

            // If we have an autoref followed by unsizing at the end, fix the unsize target.
            if let [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] =
                adjustments[..]
            {
                *target = method.sig.inputs()[0];
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a comment for bfs(), change 'ondeck' var name to 'discovered'<commit_after><|endoftext|>


<commit_before><commit_msg>Simple reader for float numbers without exp<commit_after><|endoftext|>


<commit_before><commit_msg>Remove some excess code<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor Board::new to use set_hex<commit_after><|endoftext|>


<commit_before><commit_msg>Use vectors to store rotor notches<commit_after><|endoftext|>


<commit_before><commit_msg>Remove trailing comma<commit_after><|endoftext|>


<commit_before><commit_msg>Log both benchmark stdout and stderr<commit_after><|endoftext|>