use super::*;
impl<N: Network> Parser for Operand<N> {
#[inline]
fn parse(string: &str) -> ParserResult<Self> {
alt((
map(tag("group::GEN"), |_| Self::Literal(Literal::Group(Group::generator()))),
map(tag("self.signer"), |_| Self::Signer),
map(tag("self.caller"), |_| Self::Caller),
map(tag("block.height"), |_| Self::BlockHeight),
map(Literal::parse, |literal| Self::Literal(literal)),
map(Register::parse, |register| Self::Register(register)),
map(ProgramID::parse, |program_id| Self::ProgramID(program_id)),
))(string)
}
}
impl<N: Network> FromStr for Operand<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 Operand<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
impl<N: Network> Display for Operand<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Literal(literal) => Display::fmt(literal, f),
Self::Register(register) => Display::fmt(register, f),
Self::ProgramID(program_id) => Display::fmt(program_id, f),
Self::Signer => write!(f, "self.signer"),
Self::Caller => write!(f, "self.caller"),
Self::BlockHeight => write!(f, "block.height"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::network::Testnet3;
type CurrentNetwork = Testnet3;
#[test]
fn test_operand_parse() -> Result<()> {
let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
assert_eq!(Operand::Register(Register::from_str("r0")?), operand);
let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
assert_eq!(Operand::Register(Register::from_str("r0.owner")?), operand);
let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
assert_eq!(Operand::ProgramID(ProgramID::from_str("howard.aleo")?), operand);
let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
assert_eq!(Operand::Signer, operand);
let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
assert_eq!(Operand::Caller, operand);
let operand = Operand::<CurrentNetwork>::parse("block.height").unwrap().1;
assert_eq!(Operand::BlockHeight, operand);
let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
assert_eq!(Operand::Literal(Literal::Group(Group::generator())), operand);
let (remainder, operand) = Operand::<CurrentNetwork>::parse("1field.private").unwrap();
assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
assert_eq!(".private", remainder);
Ok(())
}
#[test]
fn test_operand_display() {
let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
assert_eq!(format!("{operand}"), "1field");
let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
assert_eq!(format!("{operand}"), "r0");
let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
assert_eq!(format!("{operand}"), "r0.owner");
let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
assert_eq!(format!("{operand}"), "howard.aleo");
let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
assert_eq!(format!("{operand}"), "self.signer");
let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
assert_eq!(format!("{operand}"), "self.caller");
let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
assert_eq!(
format!("{operand}"),
"1540945439182663264862696551825005342995406165131907382295858612069623286213group"
);
}
#[test]
fn test_operand_from_str_fails() -> Result<()> {
assert!(Operand::<CurrentNetwork>::from_str("1field.private").is_err());
Ok(())
}
}