1mod impls;
2mod scalar;
3
4#[cfg(test)]
5mod tests;
6
7use std::io;
8
9use crate::{Config, DecoderContext, EncoderContext, Preamble};
10
11pub use scalar::Scalar;
12
13pub trait EncodableElement: Element {
15 fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]);
22
23 fn to_vec(&self, ctx: &mut EncoderContext) -> Vec<u8> {
25 let len = Self::len(ctx.config());
26 let mut bytes = vec![0u8; len];
27
28 self.to_buffer(ctx, &mut bytes);
29
30 bytes
31 }
32
33 fn encode<'a>(&self, ctx: &mut EncoderContext, buf: &'a mut [u8]) -> &'a mut [u8] {
37 self.to_buffer(ctx, buf);
38
39 &mut buf[Self::len(ctx.config())..]
40 }
41
42 fn try_to_writer<W>(&self, mut writer: W, ctx: &mut EncoderContext) -> io::Result<usize>
44 where
45 W: io::Write,
46 {
47 writer.write(&self.to_vec(ctx))
48 }
49}
50
51pub trait DecodableElement: Sized + Element {
53 fn try_from_buffer_in_place<'a, 'b>(
58 &'a mut self,
59 ctx: &DecoderContext<'a>,
60 buf: &'b [u8],
61 ) -> io::Result<()>;
62
63 fn try_from_buffer<'b>(ctx: &DecoderContext, buf: &'b [u8]) -> io::Result<Self> {
65 let mut slf = Self::default();
66
67 slf.try_from_buffer_in_place(ctx, buf)?;
68
69 Ok(slf)
70 }
71
72 fn try_decode_in_place<'a, 'b>(
76 &mut self,
77 ctx: &DecoderContext<'a>,
78 buf: &'b [u8],
79 ) -> io::Result<&'b [u8]> {
80 self.try_from_buffer_in_place(ctx, buf)
81 .map(|_| &buf[Self::len(ctx.config())..])
82 }
83
84 fn try_decode<'a, 'b>(ctx: &DecoderContext<'a>, buf: &'b [u8]) -> io::Result<(Self, &'b [u8])> {
88 let mut slf = Self::default();
89
90 let buf = slf.try_decode_in_place(ctx, buf)?;
91
92 Ok((slf, buf))
93 }
94
95 fn try_from_reader<R>(ctx: &DecoderContext, mut reader: R) -> io::Result<Self>
97 where
98 R: io::Read,
99 {
100 let mut slf = vec![0u8; Self::len(ctx.config())];
101
102 let _ = reader.read(&mut slf)?;
103
104 Self::try_from_buffer(ctx, &slf)
105 }
106}
107
108pub trait Element: Default {
110 fn len(ctx: &Config) -> usize;
118
119 fn validate(&self, preamble: &Preamble) -> io::Result<()>;
121
122 fn validate_buffer(config: &Config, buffer: &[u8]) -> io::Result<()> {
124 if buffer.len() < Self::len(config) {
125 return Err(io::Error::new(
126 io::ErrorKind::InvalidData,
127 "the provided buffer isn't big enough",
128 ));
129 }
130
131 Ok(())
132 }
133}