use super::*;
impl<N: Network> FromBytes for Literal<N> {
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let index = u16::read_le(&mut reader)?;
let literal = match index {
0 => Self::Address(Address::read_le(&mut reader)?),
1 => Self::Boolean(Boolean::read_le(&mut reader)?),
2 => Self::Field(Field::read_le(&mut reader)?),
3 => Self::Group(Group::read_le(&mut reader)?),
4 => Self::I8(I8::read_le(&mut reader)?),
5 => Self::I16(I16::read_le(&mut reader)?),
6 => Self::I32(I32::read_le(&mut reader)?),
7 => Self::I64(I64::read_le(&mut reader)?),
8 => Self::I128(I128::read_le(&mut reader)?),
9 => Self::U8(U8::read_le(&mut reader)?),
10 => Self::U16(U16::read_le(&mut reader)?),
11 => Self::U32(U32::read_le(&mut reader)?),
12 => Self::U64(U64::read_le(&mut reader)?),
13 => Self::U128(U128::read_le(&mut reader)?),
14 => Self::Scalar(Scalar::read_le(&mut reader)?),
15 => Self::Signature(Box::new(Signature::read_le(&mut reader)?)),
16 => Self::String(StringType::read_le(&mut reader)?),
17.. => return Err(error(format!("Failed to decode literal variant {index}"))),
};
Ok(literal)
}
}
impl<N: Network> ToBytes for Literal<N> {
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
type Size = u16;
match self {
Self::Address(primitive) => {
(0 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::Boolean(primitive) => {
(1 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::Field(primitive) => {
(2 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::Group(primitive) => {
(3 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::I8(primitive) => {
(4 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::I16(primitive) => {
(5 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::I32(primitive) => {
(6 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::I64(primitive) => {
(7 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::I128(primitive) => {
(8 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::U8(primitive) => {
(9 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::U16(primitive) => {
(10 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::U32(primitive) => {
(11 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::U64(primitive) => {
(12 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::U128(primitive) => {
(13 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::Scalar(primitive) => {
(14 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::Signature(primitive) => {
(15 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
Self::String(primitive) => {
(16 as Size).write_le(&mut writer)?;
primitive.write_le(&mut writer)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use snarkvm_console_network::Testnet3;
type CurrentNetwork = Testnet3;
const ITERATIONS: u32 = 1000;
fn check_bytes(expected: Literal<CurrentNetwork>) -> Result<()> {
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Literal::read_le(&expected_bytes[..])?);
Ok(())
}
#[test]
fn test_bytes() -> Result<()> {
let rng = &mut TestRng::default();
for _ in 0..ITERATIONS {
let private_key = snarkvm_console_account::PrivateKey::<CurrentNetwork>::new(rng)?;
check_bytes(Literal::<CurrentNetwork>::Address(Address::try_from(private_key)?))?;
check_bytes(Literal::<CurrentNetwork>::Boolean(Boolean::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::Field(Uniform::rand(rng)))?;
check_bytes(Literal::<CurrentNetwork>::Group(Uniform::rand(rng)))?;
check_bytes(Literal::<CurrentNetwork>::I8(I8::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::I16(I16::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::I32(I32::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::I64(I64::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::I128(I128::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::U8(U8::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::U16(U16::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::U32(U32::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::U64(U64::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::U128(U128::new(Uniform::rand(rng))))?;
check_bytes(Literal::<CurrentNetwork>::Scalar(Uniform::rand(rng)))?;
check_bytes(Literal::sample(LiteralType::Signature, rng))?;
check_bytes(Literal::<CurrentNetwork>::String(StringType::rand(rng)))?;
}
Ok(())
}
}