foundation_ur/ur/
encoder.rs1use crate::{fountain, ur::UR};
8
9use core::str;
10
11#[cfg(feature = "alloc")]
13pub type Encoder<'a, 'b> = BaseEncoder<'a, 'b, fountain::encoder::Alloc>;
14
15#[cfg(feature = "alloc")]
16impl<'a, 'b> Encoder<'a, 'b> {
17 pub const fn new() -> Self {
19 Self {
20 fountain: fountain::encoder::Encoder::new(),
21 ur_type: None,
22 }
23 }
24}
25
26pub type HeaplessEncoder<'a, 'b, const MAX_FRAGMENT_LEN: usize, const MAX_SEQUENCE_COUNT: usize> =
30 BaseEncoder<'a, 'b, fountain::encoder::Heapless<MAX_FRAGMENT_LEN, MAX_SEQUENCE_COUNT>>;
31
32impl<'a, 'b, const MAX_FRAGMENT_LEN: usize, const MAX_SEQUENCE_COUNT: usize>
33 HeaplessEncoder<'a, 'b, MAX_FRAGMENT_LEN, MAX_SEQUENCE_COUNT>
34{
35 pub const fn new() -> Self {
37 Self {
38 fountain: fountain::encoder::HeaplessEncoder::new(),
39 ur_type: None,
40 }
41 }
42}
43
44pub struct BaseEncoder<'a, 'b, T: fountain::encoder::Types> {
50 ur_type: Option<&'a str>,
51 fountain: fountain::encoder::BaseEncoder<'b, T>,
52}
53
54impl<'a, 'b, T: fountain::encoder::Types> BaseEncoder<'a, 'b, T> {
55 pub fn start(&mut self, ur_type: &'a str, message: &'b [u8], max_fragment_length: usize) {
69 self.ur_type = Some(ur_type);
70 self.fountain.start(message, max_fragment_length);
71 }
72
73 #[inline]
87 pub fn current_sequence(&self) -> u32 {
88 self.fountain.current_sequence()
89 }
90
91 #[inline]
102 pub fn sequence_count(&self) -> u32 {
103 self.fountain.sequence_count()
104 }
105
106 pub fn next_part(&mut self) -> UR {
112 UR::MultiPartDeserialized {
113 ur_type: self.ur_type.expect("encoder is not initialized"),
114 fragment: self.fountain.next_part(),
115 }
116 }
117}
118
119#[cfg(test)]
120#[cfg(feature = "alloc")]
121pub mod tests {
122 use super::*;
123 use crate::ur::tests::make_message_ur;
124
125 #[test]
126 fn test_ur_encoder() {
127 const TEST_VECTORS: &[&str] = &[
128 "ur:bytes/1-9/lpadascfadaxcywenbpljkhdcahkadaemejtswhhylkepmykhhtsytsnoyoyaxaedsuttydmmhhpktpmsrjtdkgslpgh",
129 "ur:bytes/2-9/lpaoascfadaxcywenbpljkhdcagwdpfnsboxgwlbaawzuefywkdplrsrjynbvygabwjldapfcsgmghhkhstlrdcxaefz",
130 "ur:bytes/3-9/lpaxascfadaxcywenbpljkhdcahelbknlkuejnbadmssfhfrdpsbiegecpasvssovlgeykssjykklronvsjksopdzmol",
131 "ur:bytes/4-9/lpaaascfadaxcywenbpljkhdcasotkhemthydawydtaxneurlkosgwcekonertkbrlwmplssjtammdplolsbrdzcrtas",
132 "ur:bytes/5-9/lpahascfadaxcywenbpljkhdcatbbdfmssrkzmcwnezelennjpfzbgmuktrhtejscktelgfpdlrkfyfwdajldejokbwf",
133 "ur:bytes/6-9/lpamascfadaxcywenbpljkhdcackjlhkhybssklbwefectpfnbbectrljectpavyrolkzczcpkmwidmwoxkilghdsowp",
134 "ur:bytes/7-9/lpatascfadaxcywenbpljkhdcavszmwnjkwtclrtvaynhpahrtoxmwvwatmedibkaegdosftvandiodagdhthtrlnnhy",
135 "ur:bytes/8-9/lpayascfadaxcywenbpljkhdcadmsponkkbbhgsoltjntegepmttmoonftnbuoiyrehfrtsabzsttorodklubbuyaetk",
136 "ur:bytes/9-9/lpasascfadaxcywenbpljkhdcajskecpmdckihdyhphfotjojtfmlnwmadspaxrkytbztpbauotbgtgtaeaevtgavtny",
137 "ur:bytes/10-9/lpbkascfadaxcywenbpljkhdcahkadaemejtswhhylkepmykhhtsytsnoyoyaxaedsuttydmmhhpktpmsrjtwdkiplzs",
138 "ur:bytes/11-9/lpbdascfadaxcywenbpljkhdcahelbknlkuejnbadmssfhfrdpsbiegecpasvssovlgeykssjykklronvsjkvetiiapk",
139 "ur:bytes/12-9/lpbnascfadaxcywenbpljkhdcarllaluzmdmgstospeyiefmwejlwtpedamktksrvlcygmzemovovllarodtmtbnptrs",
140 "ur:bytes/13-9/lpbtascfadaxcywenbpljkhdcamtkgtpknghchchyketwsvwgwfdhpgmgtylctotzopdrpayoschcmhplffziachrfgd",
141 "ur:bytes/14-9/lpbaascfadaxcywenbpljkhdcapazewnvonnvdnsbyleynwtnsjkjndeoldydkbkdslgjkbbkortbelomueekgvstegt",
142 "ur:bytes/15-9/lpbsascfadaxcywenbpljkhdcaynmhpddpzmversbdqdfyrehnqzlugmjzmnmtwmrouohtstgsbsahpawkditkckynwt",
143 "ur:bytes/16-9/lpbeascfadaxcywenbpljkhdcawygekobamwtlihsnpalnsghenskkiynthdzotsimtojetprsttmukirlrsbtamjtpd",
144 "ur:bytes/17-9/lpbyascfadaxcywenbpljkhdcamklgftaxykpewyrtqzhydntpnytyisincxmhtbceaykolduortotiaiaiafhiaoyce",
145 "ur:bytes/18-9/lpbgascfadaxcywenbpljkhdcahkadaemejtswhhylkepmykhhtsytsnoyoyaxaedsuttydmmhhpktpmsrjtntwkbkwy",
146 "ur:bytes/19-9/lpbwascfadaxcywenbpljkhdcadekicpaajootjzpsdrbalpeywllbdsnbinaerkurspbncxgslgftvtsrjtksplcpeo",
147 "ur:bytes/20-9/lpbbascfadaxcywenbpljkhdcayapmrleeleaxpasfrtrdkncffwjyjzgyetdmlewtkpktgllepfrltataztksmhkbot",
148 ];
149
150 let ur = make_message_ur(256, "Wolf");
151
152 fn test<'a, T: fountain::encoder::Types>(
153 encoder: &mut BaseEncoder<'static, 'a, T>,
154 ur: &'a [u8],
155 ) {
156 encoder.start("bytes", &ur, 30);
157 assert_eq!(encoder.sequence_count(), 9);
158 for (index, &part) in TEST_VECTORS.iter().enumerate() {
159 assert_eq!(encoder.current_sequence(), index.try_into().unwrap());
160 assert_eq!(encoder.next_part().to_string(), part);
161 }
162 }
163
164 let mut heapless_encoder: HeaplessEncoder<'_, '_, 30, 16> = HeaplessEncoder::new();
165 let mut encoder = Encoder::new();
166
167 test(&mut heapless_encoder, &ur);
168 test(&mut encoder, &ur);
169 }
170}