diff options
Diffstat (limited to 'src/address')
| -rw-r--r-- | src/address/mod.rs | 163 | 
1 files changed, 163 insertions, 0 deletions
| diff --git a/src/address/mod.rs b/src/address/mod.rs new file mode 100644 index 0000000..7146d01 --- /dev/null +++ b/src/address/mod.rs @@ -0,0 +1,163 @@ +use core::hash::Hash; + +use core::fmt::{self, Debug, Display, Formatter}; + +use core::ops::{Add, Sub, AddAssign, SubAssign}; + +use num_traits::identities; +use num_traits::{Bounded, WrappingAdd, WrappingSub, CheckedAdd, CheckedSub}; + +#[cfg(feature="use-serde")] +use serde::{Deserialize, Serialize}; + +pub trait AddressBase where Self: +    Debug + Display + AddressDisplay + +    Copy + Clone + Sized + Hash + +    Ord + Eq + PartialEq + Bounded + +    Add<Output=Self> + Sub<Output=Self> + +    AddAssign + SubAssign + +    WrappingAdd + WrappingSub + +    CheckedAdd + CheckedSub + +    Hash + +    identities::One + identities::Zero { +    fn to_linear(&self) -> usize; +} + +#[cfg(all(feature="use-serde", feature="address-parse"))] +pub trait Address where Self: +    AddressBase + +    Serialize + for<'de> Deserialize<'de> + +    AddrParse { +} + +#[cfg(all(feature="use-serde", not(feature="address-parse")))] +pub trait Address where Self: +    AddressBase + +    Serialize + for<'de> Deserialize<'de> { +} + +#[cfg(all(not(feature="use-serde"), feature="address-parse"))] +pub trait Address where Self: +    AddressBase + AddrParse { +} + +#[cfg(all(not(feature="use-serde"), not(feature="address-parse")))] +pub trait Address where Self: AddressBase { } + +impl AddressBase for u16 { +    fn to_linear(&self) -> usize { *self as usize } +} + +impl Address for u16 {} + +impl AddressBase for u32 { +    fn to_linear(&self) -> usize { *self as usize } +} + +impl Address for u32 {} + +impl AddressBase for u64 { +    fn to_linear(&self) -> usize { *self as usize } +} + +impl Address for u64 {} + +impl AddressBase for usize { +    fn to_linear(&self) -> usize { *self } +} + +impl Address for usize {} + +pub trait AddressDisplay { +    fn show(&self, f: &mut Formatter) -> fmt::Result; +} + +impl AddressDisplay for usize { +    fn show(&self, f: &mut Formatter) -> fmt::Result { +        write!(f, "{:#x}", self) +    } +} + +impl AddressDisplay for u64 { +    fn show(&self, f: &mut Formatter) -> fmt::Result { +        write!(f, "{:#x}", self) +    } +} + +impl AddressDisplay for u32 { +    fn show(&self, f: &mut Formatter) -> fmt::Result { +        write!(f, "{:#x}", self) +    } +} + +impl AddressDisplay for u16 { +    fn show(&self, f: &mut Formatter) -> fmt::Result { +        write!(f, "{:#x}", self) +    } +} + +/* + * TODO: this should be FromStr. + * that would require newtyping address primitives, though + * + * this is not out of the question, BUT is way more work than + * i want to put in right now + * + * this is one of those "clean it up later" situations + */ +#[cfg(feature="address-parse")] +use core::str::FromStr; + +#[cfg(feature="address-parse")] +pub trait AddrParse: Sized { +    type Err; +    fn parse_from(s: &str) -> Result<Self, Self::Err>; +} + +#[cfg(feature="address-parse")] +impl AddrParse for usize { +    type Err = core::num::ParseIntError; +    fn parse_from(s: &str) -> Result<Self, Self::Err> { +        if s.starts_with("0x") { +            usize::from_str_radix(&s[2..], 16) +        } else { +            usize::from_str(s) +        } +    } +} + +#[cfg(feature="address-parse")] +impl AddrParse for u64 { +    type Err = core::num::ParseIntError; +    fn parse_from(s: &str) -> Result<Self, Self::Err> { +        if s.starts_with("0x") { +            u64::from_str_radix(&s[2..], 16) +        } else { +            u64::from_str(s) +        } +    } +} + +#[cfg(feature="address-parse")] +impl AddrParse for u32 { +    type Err = core::num::ParseIntError; +    fn parse_from(s: &str) -> Result<Self, Self::Err> { +        if s.starts_with("0x") { +            u32::from_str_radix(&s[2..], 16) +        } else { +            u32::from_str(s) +        } +    } +} + +#[cfg(feature="address-parse")] +impl AddrParse for u16 { +    type Err = core::num::ParseIntError; +    fn parse_from(s: &str) -> Result<Self, Self::Err> { +        if s.starts_with("0x") { +            u16::from_str_radix(&s[2..], 16) +        } else { +            u16::from_str(s) +        } +    } +} | 
