1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
mod name_type;
use crate::bytes::{NumBytes, Read, Write};
use core::{
convert::TryFrom,
fmt,
str::{self, FromStr},
};
pub use eosio_numstr::ParseNameError;
use eosio_numstr::{name_from_bytes, name_to_bytes};
#[derive(
Debug,
PartialEq,
Eq,
Clone,
Copy,
Default,
Hash,
PartialOrd,
Ord,
Read,
Write,
NumBytes,
)]
#[eosio(crate_path = "crate::bytes")]
pub struct Name(u64);
impl Name {
#[inline]
#[must_use]
pub const fn new(value: u64) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn as_u64(&self) -> u64 {
self.0
}
}
impl From<u64> for Name {
#[inline]
#[must_use]
fn from(n: u64) -> Self {
Self(n)
}
}
impl From<Name> for u64 {
#[inline]
#[must_use]
fn from(i: Name) -> Self {
i.0
}
}
impl FromStr for Name {
type Err = ParseNameError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let name = name_from_bytes(s.bytes())?;
Ok(name.into())
}
}
impl fmt::Display for Name {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let bytes = name_to_bytes(self.0);
let value = str::from_utf8(&bytes)
.map(|s| s.trim_end_matches('.'))
.map_err(|_| fmt::Error)?;
write!(f, "{}", value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
use proptest::prelude::*;
proptest! {
#[test]
fn from_str_to_string(input in "[[1-5][a-z]]{0,12}[a-j]{0,1}") {
let name = Name::from_str(&input).expect("Failed to parse name from str");
let string = name.to_string();
prop_assert_eq!(string, input);
}
}
}