Skip to content

Commit

Permalink
feat: encode and don't consume the value
Browse files Browse the repository at this point in the history
  • Loading branch information
lwshang committed Jan 22, 2025
1 parent d5a5127 commit 9bbdb69
Showing 1 changed file with 59 additions and 1 deletion.
60 changes: 59 additions & 1 deletion rust/candid/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,29 @@ pub fn write_args<Tuple: ArgumentEncoder, Writer: std::io::Write>(
ser.serialize(writer)
}

/// Serialize an encoding of a tuple and write it to a `Write` buffer.
///
/// ```
/// # use candid::Decode;
/// # use candid::write_args;
/// let golden1 = 1u64;
/// let golden2 = "hello";
/// let mut buffer = Vec::new();
/// write_args_ref(&mut buffer, &(golden1, golden2)).unwrap();
///
/// let (value1, value2) = Decode!(&buffer, u64, String).unwrap();
/// assert_eq!(golden1, value1);
/// assert_eq!(golden2, value2);
/// ```
pub fn write_args_ref<Tuple: ArgumentEncoder, Writer: std::io::Write>(
writer: &mut Writer,
arguments: &Tuple,
) -> Result<()> {
let mut ser = IDLBuilder::new();
arguments.encode_ref(&mut ser)?;
ser.serialize(writer)
}

/// Serialize an encoding of a tuple to a vector of bytes.
///
/// ```
Expand All @@ -213,6 +236,25 @@ pub fn encode_args<Tuple: ArgumentEncoder>(arguments: Tuple) -> Result<Vec<u8>>
Ok(result)
}

/// Serialize an encoding of a tuple to a vector of bytes.
///
/// ```
/// # use candid::Decode;
/// # use candid::encode_args;
/// let golden1 = 1u64;
/// let golden2 = "hello";
/// let buffer = encode_args_ref(&(golden1, golden2)).unwrap();
///
/// let (value1, value2) = Decode!(&buffer, u64, String).unwrap();
/// assert_eq!(golden1, value1);
/// assert_eq!(golden2, value2);
/// ```
pub fn encode_args_ref<Tuple: ArgumentEncoder>(arguments: &Tuple) -> Result<Vec<u8>> {
let mut result = Vec::new();
write_args_ref(&mut result, arguments)?;
Ok(result)
}

/// Serialize a single value to a vector of bytes.
///
/// ```
Expand Down Expand Up @@ -245,11 +287,18 @@ impl<'a> ArgumentDecoder<'a> for () {
pub trait ArgumentEncoder {
/// Encode a value of type [Self].
fn encode(self, ser: &mut IDLBuilder) -> Result<()>;

/// Encode a reference value of type [Self].
fn encode_ref(&self, ser: &mut IDLBuilder) -> Result<()>;
}

/// Decode an empty tuple.
impl ArgumentEncoder for () {
fn encode(self, _de: &mut IDLBuilder) -> Result<()> {
fn encode(self, _ser: &mut IDLBuilder) -> Result<()> {
Ok(())
}

fn encode_ref(&self, _ser: &mut IDLBuilder) -> Result<()> {
Ok(())
}
}
Expand Down Expand Up @@ -287,6 +336,15 @@ macro_rules! encode_impl {

Ok(())
}

fn encode_ref(&self, ser: &mut IDLBuilder) -> Result<()> {
let ( $( $id, )* ) = self;
$(
ser.arg(&$id)?;
)*

Ok(())
}
}
}
}
Expand Down

0 comments on commit 9bbdb69

Please sign in to comment.