#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(feature = "nightly", feature(stmt_expr_attributes))]
#![forbid(unsafe_code)]
#![deny(non_upper_case_globals)]
#![deny(non_camel_case_types)]
#![deny(unused_mut)]
#[macro_use]
extern crate amplify;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate clap;
use std::io;
use std::str::FromStr;
use crate::consensus::{Decodable, Encodable};
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[macro_use]
pub mod consensus;
pub mod bitcoin;
pub mod blockchain;
pub mod crypto;
pub(crate) mod hash;
pub mod monero;
pub mod protocol;
pub mod role;
pub mod script;
pub mod swap;
pub mod trade;
pub mod transaction;
#[derive(Error, Debug)]
pub enum Error {
#[error("Consensus error: {0}")]
Consensus(#[from] consensus::Error),
#[error("Cryptographic error: {0}")]
Crypto(#[from] crypto::Error),
#[error("Fee Strategy error: {0}")]
FeeStrategy(#[from] blockchain::FeeStrategyError),
#[error("Transaction error: {0}")]
Transaction(#[from] transaction::Error),
#[error("Trade error: {0}")]
Trade(#[from] trade::Error),
}
pub type Res<T> = Result<T, Error>;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Display, Serialize, Deserialize,
)]
#[display(inner)]
pub struct Uuid(uuid::Uuid);
impl Uuid {
pub fn new() -> Self {
Self(uuid::Uuid::new_v4())
}
pub fn random() -> Self {
Self::new()
}
}
impl Default for Uuid {
fn default() -> Self {
Self::new()
}
}
impl From<uuid::Uuid> for Uuid {
fn from(u: uuid::Uuid) -> Self {
Self(u)
}
}
impl From<trade::DealId> for Uuid {
fn from(id: trade::DealId) -> Self {
id.0
}
}
impl From<swap::SwapId> for Uuid {
fn from(id: swap::SwapId) -> Self {
id.0
}
}
impl FromStr for Uuid {
type Err = uuid::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(uuid::Uuid::from_str(s)?))
}
}
impl AsRef<uuid::Uuid> for Uuid {
fn as_ref(&self) -> &uuid::Uuid {
&self.0
}
}
impl Encodable for Uuid {
fn consensus_encode<W: io::Write>(&self, s: &mut W) -> Result<usize, io::Error> {
self.0.to_bytes_le().consensus_encode(s)
}
}
impl Decodable for Uuid {
fn consensus_decode<D: io::Read>(d: &mut D) -> Result<Self, consensus::Error> {
Ok(Self(uuid::Uuid::from_bytes_le(
Decodable::consensus_decode(d)?,
)))
}
}
impl strict_encoding::StrictEncode for Uuid {
fn strict_encode<E: io::Write>(&self, mut e: E) -> Result<usize, strict_encoding::Error> {
self.as_ref().to_bytes_le().strict_encode(&mut e)
}
}
impl strict_encoding::StrictDecode for Uuid {
fn strict_decode<D: io::Read>(mut d: D) -> Result<Self, strict_encoding::Error> {
Ok(Self(uuid::Uuid::from_bytes_le(<[u8; 16]>::strict_decode(
&mut d,
)?)))
}
}
#[cfg(test)]
mod tests {
use super::Uuid;
use uuid::uuid;
#[test]
fn serialize_swapid_in_yaml() {
let id: Uuid = uuid!("67e55044-10b1-426f-9247-bb680e5fe0c8").into();
let s = serde_yaml::to_string(&id).expect("Encode swap id in yaml");
assert_eq!("---\n67e55044-10b1-426f-9247-bb680e5fe0c8\n", s);
}
#[test]
fn deserialize_swapid_from_yaml() {
let s = "---\n67e55044-10b1-426f-9247-bb680e5fe0c8\n";
let id: Uuid = serde_yaml::from_str(&s).expect("Decode uuid from yaml");
assert_eq!(id, uuid!("67e55044-10b1-426f-9247-bb680e5fe0c8").into(),);
}
}