diff options
Diffstat (limited to 'src/address/mod.rs')
-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) + } + } +} |