use super::*;
impl<N: Network> Parser for Register<N> {
#[inline]
fn parse(string: &str) -> ParserResult<Self> {
let (string, _) = tag("r")(string)?;
let (string, locator) =
map_res(recognize(many1(one_of("0123456789"))), |locator: &str| locator.parse::<u64>())(string)?;
let (string, identifiers): (&str, Vec<Identifier<N>>) =
map_res(many0(pair(tag("."), Identifier::parse)), |identifiers| {
if identifiers.len() <= N::MAX_DATA_DEPTH {
Ok(identifiers.iter().cloned().map(|(_, identifier)| identifier).collect())
} else {
Err(error(format!("Register \'r{locator}\' has too many identifiers ({})", identifiers.len())))
}
})(string)?;
Ok((string, match identifiers.len() {
0 => Self::Locator(locator),
_ => Self::Member(locator, identifiers),
}))
}
}
impl<N: Network> FromStr for Register<N> {
type Err = Error;
#[inline]
fn from_str(string: &str) -> Result<Self> {
match Self::parse(string) {
Ok((remainder, object)) => {
ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
Ok(object)
}
Err(error) => bail!("Failed to parse string. {error}"),
}
}
}
impl<N: Network> Debug for Register<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
impl<N: Network> Display for Register<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Locator(locator) => write!(f, "r{locator}"),
Self::Member(locator, identifiers) => {
write!(f, "r{locator}")?;
for identifier in identifiers {
write!(f, ".{identifier}")?;
}
Ok(())
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use snarkvm_console_network::Testnet3;
type CurrentNetwork = Testnet3;
#[test]
fn test_register_display() -> Result<()> {
assert_eq!("r0", Register::<CurrentNetwork>::Locator(0).to_string());
assert_eq!("r1", Register::<CurrentNetwork>::Locator(1).to_string());
assert_eq!("r2", Register::<CurrentNetwork>::Locator(2).to_string());
assert_eq!("r3", Register::<CurrentNetwork>::Locator(3).to_string());
assert_eq!("r4", Register::<CurrentNetwork>::Locator(4).to_string());
assert_eq!("r0.owner", Register::<CurrentNetwork>::Member(0, vec![Identifier::from_str("owner")?]).to_string());
assert_eq!("r1.owner", Register::<CurrentNetwork>::Member(1, vec![Identifier::from_str("owner")?]).to_string());
assert_eq!("r2.owner", Register::<CurrentNetwork>::Member(2, vec![Identifier::from_str("owner")?]).to_string());
assert_eq!("r3.owner", Register::<CurrentNetwork>::Member(3, vec![Identifier::from_str("owner")?]).to_string());
assert_eq!("r4.owner", Register::<CurrentNetwork>::Member(4, vec![Identifier::from_str("owner")?]).to_string());
Ok(())
}
#[test]
fn test_register_to_string() -> Result<()> {
assert_eq!(Register::<CurrentNetwork>::Locator(0).to_string(), "r0".to_string());
assert_eq!(Register::<CurrentNetwork>::Locator(1).to_string(), "r1".to_string());
assert_eq!(Register::<CurrentNetwork>::Locator(2).to_string(), "r2".to_string());
assert_eq!(Register::<CurrentNetwork>::Locator(3).to_string(), "r3".to_string());
assert_eq!(Register::<CurrentNetwork>::Locator(4).to_string(), "r4".to_string());
assert_eq!(
Register::<CurrentNetwork>::Member(0, vec![Identifier::from_str("owner")?]).to_string(),
"r0.owner".to_string()
);
assert_eq!(
Register::<CurrentNetwork>::Member(1, vec![Identifier::from_str("owner")?]).to_string(),
"r1.owner".to_string()
);
assert_eq!(
Register::<CurrentNetwork>::Member(2, vec![Identifier::from_str("owner")?]).to_string(),
"r2.owner".to_string()
);
assert_eq!(
Register::<CurrentNetwork>::Member(3, vec![Identifier::from_str("owner")?]).to_string(),
"r3.owner".to_string()
);
assert_eq!(
Register::<CurrentNetwork>::Member(4, vec![Identifier::from_str("owner")?]).to_string(),
"r4.owner".to_string()
);
Ok(())
}
#[test]
fn test_register_parse() -> Result<()> {
assert_eq!(("", Register::<CurrentNetwork>::Locator(0)), Register::parse("r0").unwrap());
assert_eq!(("", Register::<CurrentNetwork>::Locator(1)), Register::parse("r1").unwrap());
assert_eq!(("", Register::<CurrentNetwork>::Locator(2)), Register::parse("r2").unwrap());
assert_eq!(("", Register::<CurrentNetwork>::Locator(3)), Register::parse("r3").unwrap());
assert_eq!(("", Register::<CurrentNetwork>::Locator(4)), Register::parse("r4").unwrap());
assert_eq!(
("", Register::<CurrentNetwork>::Member(0, vec![Identifier::from_str("owner")?])),
Register::parse("r0.owner").unwrap()
);
assert_eq!(
("", Register::<CurrentNetwork>::Member(1, vec![Identifier::from_str("owner")?])),
Register::parse("r1.owner").unwrap()
);
assert_eq!(
("", Register::<CurrentNetwork>::Member(2, vec![Identifier::from_str("owner")?])),
Register::parse("r2.owner").unwrap()
);
assert_eq!(
("", Register::<CurrentNetwork>::Member(3, vec![Identifier::from_str("owner")?])),
Register::parse("r3.owner").unwrap()
);
assert_eq!(
("", Register::<CurrentNetwork>::Member(4, vec![Identifier::from_str("owner")?])),
Register::parse("r4.owner").unwrap()
);
for i in 1..=CurrentNetwork::MAX_DATA_DEPTH {
let mut string = "r0.".to_string();
for _ in 0..i {
string.push_str("owner.");
}
string.pop(); assert_eq!(
("", Register::<CurrentNetwork>::Member(0, vec![Identifier::from_str("owner")?; i])),
Register::<CurrentNetwork>::parse(&string).unwrap()
);
}
Ok(())
}
#[test]
fn test_register_parser_fails() {
assert!(Register::<CurrentNetwork>::parse("").is_err());
assert!(Register::<CurrentNetwork>::parse("r").is_err());
for i in CurrentNetwork::MAX_DATA_DEPTH + 1..CurrentNetwork::MAX_DATA_DEPTH * 2 {
let mut string = "r0.".to_string();
for _ in 0..i {
string.push_str("owner.");
}
string.pop(); assert!(Register::<CurrentNetwork>::parse(&string).is_err());
}
}
}