1use crate::{
2 atom::{Atom, Builder as AtomBuilder, Iter as AtomIter},
3 cell::Cell,
4 convert,
5 serdes::{self, Cue, Jam},
6 Rc,
7};
8use std::{
9 collections::HashMap,
10 fmt::{Display, Error, Formatter},
11 mem::drop,
12};
13
14#[derive(Clone, Debug, Eq, Hash, PartialEq)]
16pub enum Noun {
17 Atom(Atom),
19 Cell(Cell),
21}
22
23impl Noun {
24 pub const fn null() -> Self {
26 Self::Atom(Atom::null())
27 }
28
29 pub const fn is_null(&self) -> bool {
31 if let Noun::Atom(atom) = self {
32 atom.is_null()
33 } else {
34 false
35 }
36 }
37
38 pub fn hash(&self) -> u64 {
40 match self {
41 Self::Atom(atom) => atom.hash(),
42 Self::Cell(cell) => cell.hash(),
43 }
44 }
45
46 pub fn as_cell(&self) -> Option<&Cell> {
47 if let Noun::Cell(cell) = self {
48 Some(cell)
49 } else {
50 None
51 }
52 }
53
54 pub fn into_atom(&self) -> Option<Atom> {
55 if let Noun::Atom(atom) = self {
56 Some(atom.clone())
57 } else {
58 None
59 }
60 }
61
62 pub fn into_cell(&self) -> Option<Cell> {
63 if let Noun::Cell(cell) = self {
64 Some(cell.clone())
65 } else {
66 None
67 }
68 }
69
70 pub fn as_atom(&self) -> Option<&Atom> {
71 if let Noun::Atom(atom) = self {
72 Some(atom)
73 } else {
74 None
75 }
76 }
77}
78
79impl Cue for Noun {
80 fn cue(jammed_noun: Atom) -> serdes::Result<Self> {
81 fn decode_atom(bits: &mut AtomIter) -> serdes::Result<Atom> {
82 let len = {
83 let mut len_of_len = 0;
84 loop {
85 match bits.next() {
86 Some(true) => break,
87 Some(false) => len_of_len += 1,
88 None => return Err(serdes::Error::InvalidLen),
89 }
90 }
91
92 if len_of_len == 0 {
93 0
94 } else {
95 let len_bits = len_of_len - 1;
97 let mut len: u64 = 1 << len_bits;
98 for i in 0..len_bits {
99 match bits.next() {
100 Some(true) => len |= 1 << i,
101 Some(false) => len &= !(1 << i),
102 None => return Err(serdes::Error::InvalidLen),
103 }
104 }
105 len
106 }
107 };
108 if len == 0 {
109 Ok(Atom::from(0u8))
110 } else {
111 let mut atom_builder = Atom::builder();
112 for _ in 0..len {
113 let bit = bits.next().ok_or(serdes::Error::AtomBuilding)?;
114 atom_builder.push_bit(bit);
115 }
116 Ok(atom_builder.into_atom())
117 }
118 }
119
120 fn decode(
121 bits: &mut AtomIter,
122 cache: &mut HashMap<u64, Rc<Noun>>,
123 ) -> serdes::Result<Rc<Noun>> {
124 let pos = bits.pos() as u64;
125 match bits.next() {
126 Some(true) => {
127 match bits.next() {
128 Some(true) => {
130 let idx = decode_atom(bits)?
131 .as_u64()
132 .ok_or(serdes::Error::InvalidBackref)?;
133 let noun = cache.get(&idx).ok_or(serdes::Error::CacheMiss)?;
134 Ok(noun.clone())
135 }
136 Some(false) => {
138 let head = decode(bits, cache)?;
139 let tail = decode(bits, cache)?;
140
141 let cell = Rc::<Noun>::from(Cell::from([head, tail]));
142 cache.insert(pos, cell.clone());
143
144 Ok(cell)
145 }
146 None => Err(serdes::Error::InvalidTag),
147 }
148 }
149 Some(false) => {
151 let atom = Rc::<Noun>::from(decode_atom(bits)?);
152 cache.insert(pos, atom.clone());
153 Ok(atom)
154 }
155 None => unimplemented!(),
156 }
157 }
158
159 let mut bits = jammed_noun.iter();
160 let mut cache = HashMap::new();
161 let noun = decode(&mut bits, &mut cache)?;
162 drop(cache);
165 let noun = Rc::try_unwrap(noun).unwrap();
166 Ok(noun)
167 }
168}
169
170impl Display for Noun {
171 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
172 match self {
173 Self::Atom(atom) => atom.fmt(f),
174 Self::Cell(cell) => cell.fmt(f),
175 }
176 }
177}
178
179impl From<Atom> for Noun {
180 fn from(atom: Atom) -> Self {
181 Self::Atom(atom)
182 }
183}
184
185impl From<Atom> for Rc<Noun> {
186 fn from(atom: Atom) -> Self {
187 Rc::new(Noun::Atom(atom))
188 }
189}
190
191impl From<Cell> for Noun {
192 fn from(cell: Cell) -> Self {
193 Self::Cell(cell)
194 }
195}
196
197impl From<Cell> for Rc<Noun> {
198 fn from(cell: Cell) -> Self {
199 Rc::new(Noun::Cell(cell))
200 }
201}
202
203impl Jam for Noun {
204 fn jam(self) -> Atom {
205 fn encode_len(mut len: u64, bits: &mut AtomBuilder) {
206 let len_of_len = u64::BITS - len.leading_zeros();
207 for _ in 0..len_of_len {
208 bits.push_bit(false);
209 }
210 bits.push_bit(true);
211 if len_of_len != 0 {
212 while len != 1 {
214 bits.push_bit((len & 1) != 0);
215 len >>= 1;
216 }
217 }
218 }
219
220 fn encode_atom(atom: &Atom, bits: &mut AtomBuilder) {
221 bits.push_bit(false);
223 encode_len(atom.bit_len() as u64, bits);
224 for bit in atom.iter() {
225 bits.push_bit(bit);
226 }
227 }
228
229 fn encode(noun: Rc<Noun>, bits: &mut AtomBuilder, cache: &mut HashMap<Rc<Noun>, u64>) {
230 if let Some(idx) = cache.get(&noun) {
231 if let Noun::Atom(ref atom) = *noun {
232 let idx_bit_len = u64::from(u64::BITS - idx.leading_zeros());
233 let atom_bit_len = atom.bit_len() as u64;
234 if atom_bit_len <= idx_bit_len {
237 encode_atom(atom, bits);
238 return;
239 }
240 }
241 let idx = Atom::from(*idx);
242 bits.push_bit(true);
244 bits.push_bit(true);
245 encode_len(idx.bit_len() as u64, bits);
246 for bit in idx.iter() {
247 bits.push_bit(bit);
248 }
249 return;
250 }
251
252 cache.insert(noun.clone(), bits.pos() as u64);
253 match *noun {
254 Noun::Atom(ref atom) => encode_atom(atom, bits),
255 Noun::Cell(ref cell) => {
256 bits.push_bit(true);
258 bits.push_bit(false);
259 encode(cell.head(), bits, cache);
260 encode(cell.tail(), bits, cache);
261 }
262 }
263 }
264
265 let noun = Rc::new(self);
266 let mut bits = Atom::builder();
267 let mut cache = HashMap::new();
268 encode(noun, &mut bits, &mut cache);
269 bits.into_atom()
270 }
271}
272
273impl TryFrom<&&str> for Noun {
274 type Error = ();
275
276 fn try_from(string: &&str) -> Result<Self, Self::Error> {
277 Ok(Noun::from(Atom::from(*string)))
278 }
279}
280
281impl TryFrom<String> for Noun {
282 type Error = ();
283
284 fn try_from(string: String) -> Result<Self, Self::Error> {
285 Ok(Noun::from(Atom::from(string)))
286 }
287}
288
289impl<'a> TryFrom<&'a Noun> for &'a str {
290 type Error = convert::Error;
291
292 fn try_from(noun: &'a Noun) -> Result<Self, Self::Error> {
293 if let Noun::Atom(noun) = noun {
294 noun.as_str().or(Err(convert::Error::AtomToStr))
295 } else {
296 Err(convert::Error::UnexpectedCell)
297 }
298 }
299}
300
301impl TryFrom<&Noun> for String {
302 type Error = convert::Error;
303
304 fn try_from(noun: &Noun) -> Result<Self, Self::Error> {
305 if let Noun::Atom(noun) = noun {
306 if let Ok(noun) = noun.as_str() {
307 Ok(Self::from(noun))
308 } else {
309 Err(convert::Error::AtomToStr)
310 }
311 } else {
312 Err(convert::Error::UnexpectedCell)
313 }
314 }
315}
316
317#[cfg(feature = "thread-safe")]
318unsafe impl Send for Noun {}
319
320#[cfg(feature = "thread-safe")]
321unsafe impl Sync for Noun {}
322
323#[cfg(test)]
324mod tests {
325 use super::*;
326
327 #[test]
328 fn jam_cue_atom() {
329 {
331 let atom: Noun = Noun::from(Atom::from(0u8));
332 let jammed_atom = Atom::from(2u8);
333 assert_eq!(atom.clone().jam(), jammed_atom);
334 assert_eq!(Noun::cue(jammed_atom).expect("cue"), atom);
335 }
336
337 {
339 let atom: Noun = Noun::from(Atom::from(1u8));
340 let jammed_atom = Atom::from(12u8);
341 assert_eq!(atom.clone().jam(), jammed_atom);
342 assert_eq!(Noun::cue(jammed_atom).expect("cue"), atom);
343 }
344
345 {
347 let atom: Noun = Noun::from(Atom::from(2u8));
348 let jammed_atom = Atom::from(72u8);
349 assert_eq!(atom.clone().jam(), jammed_atom);
350 assert_eq!(Noun::cue(jammed_atom).expect("cue"), atom);
351 }
352
353 {
355 let atom: Noun = Noun::from(Atom::from(19u8));
356 let jammed_atom = Atom::from(2480u16);
357 assert_eq!(atom.clone().jam(), jammed_atom);
358 assert_eq!(Noun::cue(jammed_atom).expect("cue"), atom);
359 }
360
361 {
363 let atom: Noun = Noun::from(Atom::from(581_949_002u32));
364 let jammed_atom = Atom::from(1_191_831_557_952u64);
365 assert_eq!(atom.clone().jam(), jammed_atom);
366 assert_eq!(Noun::cue(jammed_atom).expect("cue"), atom);
367 }
368 }
369
370 #[test]
371 fn jam_cue_cell() {
372 {
374 let cell: Noun = Noun::from(Cell::from([0u8, 19u8]));
375 let jammed_cell = Atom::from(39_689u16);
376 assert_eq!(cell.clone().jam(), jammed_cell);
377 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
378 }
379
380 {
382 let cell: Noun = Noun::from(Cell::from([1u8, 1u8]));
383 let jammed_cell = Atom::from(817u16);
384 assert_eq!(cell.clone().jam(), jammed_cell);
385 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
386 }
387
388 {
390 let cell: Noun = Noun::from(Cell::from([10_000u16, 10_000u16]));
391 let jammed_cell = Atom::from(0b100100111001110001000011010000001u64);
392 assert_eq!(cell.clone().jam(), jammed_cell);
393 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
394 }
395
396 {
398 let cell: Noun = Noun::from(Cell::from([999_999_999u32, 999_999_999u32]));
399 let jammed_cell = Atom::from(0b100100111110111001101011001001111111111110100000001u64);
400 assert_eq!(cell.clone().jam(), jammed_cell);
401 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
402 }
403
404 {
406 let cell: Noun = Noun::from(Cell::from([222u16, 444u16, 888u16]));
407 let jammed_cell = Atom::from(250_038_217_192_960_129u64);
408 assert_eq!(cell.clone().jam(), jammed_cell);
409 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
410 }
411
412 {
414 let head = Rc::<Noun>::from(Cell::from([107u8, 110u8]));
415 let cell: Noun = Noun::from(Cell::from([head.clone(), head]));
416 let jammed_cell = Atom::from(0b1001001111011101110000110101111100000101u64);
417 assert_eq!(cell.clone().jam(), jammed_cell);
418 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
419 }
420
421 {
423 let cell: Noun = Noun::from(Cell::from([
424 0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8,
425 ]));
426
427 let jammed_cell = Atom::from(25_681_224_503_728_653_597_984_370_231_065u128);
428 assert_eq!(cell.clone().jam(), jammed_cell);
429 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
430 }
431
432 {
434 let cell: Noun = Noun::from(Cell::from([99u8, 100u8, 101u8, 102u8, 103u8, 104u8, 0u8]));
435 let jammed_cell = Atom::from(223_372_995_869_285_333_705_242_560_449u128);
436 assert_eq!(cell.clone().jam(), jammed_cell);
437 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
438 }
439
440 {
442 let head = Rc::<Noun>::from(Cell::from([222u16, 444u16, 888u16]));
443 let cell: Noun = Noun::from(Cell::from([head.clone(), head]));
444 let jammed_cell = Atom::from(170_479_614_045_978_345_989u128);
445 assert_eq!(cell.clone().jam(), jammed_cell);
446 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
447 }
448
449 {
451 let cell: Noun = Noun::from(Cell::from([
452 Noun::from(Cell::from([0u8, 1u8])),
453 Noun::from(Cell::from([1u8, 2u8])),
454 Noun::from(Cell::from([2u8, 3u8])),
455 Noun::from(Cell::from([3u8, 4u8])),
456 Noun::from(Atom::from(0u8)),
457 ]));
458 let jammed_cell = Atom::from(11_976_248_475_217_237_797u64);
459 assert_eq!(cell.clone().jam(), jammed_cell);
460 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
461 }
462
463 {
466 let cell: Noun = Noun::from(Cell::from([
467 Noun::from(Cell::from([0u8, 1u8])),
468 Noun::from(Cell::from([1u8, 2u8])),
469 Noun::from(Cell::from([2u8, 3u8])),
470 Noun::from(Cell::from([3u8, 4u8])),
471 Noun::from(Cell::from([4u8, 5u8])),
472 Noun::from(Cell::from([5u8, 6u8])),
473 Noun::from(Cell::from([6u8, 7u8])),
474 Noun::from(Cell::from([7u8, 8u8])),
475 Noun::from(Cell::from([8u8, 9u8])),
476 Noun::from(Atom::from(0u8)),
477 ]));
478 let jammed_cell = Atom::from(vec![
479 37, 23, 35, 11, 137, 46, 52, 102, 97, 226, 22, 46, 118, 97, 227, 23, 62, 4, 11,
480 130, 144, 20,
481 ]);
482 assert_eq!(cell.clone().jam(), jammed_cell);
483 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
484 }
485
486 {
490 let cell: Noun = Noun::from(Cell::from([
491 Noun::from(Cell::from([0u8, 1u8])),
492 Noun::from(Cell::from([2u8, 3u8])),
493 Noun::from(Cell::from([4u8, 5u8])),
494 Noun::from(Cell::from([6u8, 7u8])),
495 Noun::from(Cell::from([8u8, 9u8])),
496 Noun::from(Cell::from([10u8, 11u8])),
497 Noun::from(Cell::from([12u8, 13u8])),
498 Noun::from(Cell::from([14u8, 15u8])),
499 Noun::from(Cell::from([16u8, 17u8])),
500 Noun::from(Cell::from([18u8, 19u8])),
501 Noun::from(Cell::from([20u8, 21u8])),
502 Noun::from(Atom::from(0u8)),
503 ]));
504 let jammed_cell = Atom::from(vec![
505 37, 23, 18, 93, 152, 184, 133, 141, 95, 16, 132, 100, 65, 20, 178, 5, 97, 72, 23,
506 196, 33, 95, 48, 8, 139, 5, 147, 176, 89, 48, 10, 171, 2,
507 ]);
508 assert_eq!(cell.clone().jam(), jammed_cell);
509 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
510 }
511
512 {
515 let cell: Noun = Noun::from(Cell::from([
516 Cell::from(["vary", "Origin"]),
517 Cell::from(["vary", "Accept-Encoding"]),
518 ]));
519 let jammed_cell = Atom::from(vec![
520 5, 124, 187, 48, 185, 60, 224, 123, 146, 75, 59, 75, 115, 55, 19, 224, 29, 52, 54,
521 86, 6, 71, 215, 82, 228, 54, 246, 70, 150, 230, 118, 6,
522 ]);
523 assert_eq!(cell.clone().jam(), jammed_cell);
524 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
525 }
526
527 {
529 let cell: Noun = Noun::from(Cell::from(["x-cached", "HIT"]));
530 let jammed_cell = Atom::from(3_419_056_981_361_227_851_413_339_139_505_665u128);
531 assert_eq!(cell.clone().jam(), jammed_cell);
532 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
533 }
534
535 {
544 let cell: Noun = Noun::from(Cell::from([
545 Noun::from(Cell::from(["x-cached", "HIT"])),
546 Noun::from(Cell::from(["vary", "Origin"])),
547 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
548 Noun::from(Atom::from(0u8)),
549 ]));
550 let jammed_cell = Atom::from(vec![
551 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
552 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
553 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 89,
554 ]);
555 assert_eq!(cell.clone().jam(), jammed_cell);
556 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
557 }
558
559 {
569 let cell: Noun = Noun::from(Cell::from([
570 Noun::from(Cell::from(["x-cached", "HIT"])),
571 Noun::from(Cell::from(["vary", "Origin"])),
572 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
573 Noun::from(Cell::from(["connection", "keep-alive"])),
574 Noun::from(Atom::from(0u8)),
575 ]));
576 let jammed_cell = Atom::from(vec![
577 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
578 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
579 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 185, 0, 62, 99, 111, 110, 110, 101,
580 99, 116, 105, 111, 110, 128, 207, 90, 89, 25, 92, 75, 24, 91, 154, 93, 89,
581 ]);
582 assert_eq!(cell.clone().jam(), jammed_cell);
583 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
584 }
585
586 {
597 let cell: Noun = Noun::from(Cell::from([
598 Noun::from(Cell::from(["x-cached", "HIT"])),
599 Noun::from(Cell::from(["vary", "Origin"])),
600 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
601 Noun::from(Cell::from(["connection", "keep-alive"])),
602 Noun::from(Cell::from(["content-length", "59"])),
603 Noun::from(Atom::from(0u8)),
604 ]));
605
606 let jammed_cell = Atom::from(vec![
607 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
608 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
609 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 185, 0, 62, 99, 111, 110, 110, 101,
610 99, 116, 105, 111, 110, 128, 207, 90, 89, 25, 92, 75, 24, 91, 154, 93, 185, 0, 190,
611 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 208, 53, 185,
612 ]);
613 assert_eq!(cell.clone().jam(), jammed_cell);
614 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
615 }
616
617 {
629 let cell: Noun = Noun::from(Cell::from([
630 Noun::from(Cell::from(["x-cached", "HIT"])),
631 Noun::from(Cell::from(["vary", "Origin"])),
632 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
633 Noun::from(Cell::from(["connection", "keep-alive"])),
634 Noun::from(Cell::from(["content-length", "59"])),
635 Noun::from(Cell::from(["content-type", "application/json"])),
636 Noun::from(Atom::from(0u8)),
637 ]));
638
639 let jammed_cell = Atom::from(vec![
640 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
641 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
642 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 185, 0, 62, 99, 111, 110, 110, 101,
643 99, 116, 105, 111, 110, 128, 207, 90, 89, 25, 92, 75, 24, 91, 154, 93, 185, 0, 190,
644 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 208, 53, 121,
645 1, 252, 198, 222, 220, 232, 202, 220, 232, 90, 232, 242, 224, 202, 0, 255, 48, 56,
646 56, 182, 180, 177, 48, 186, 180, 55, 183, 23, 181, 185, 55, 183,
647 ]);
648 assert_eq!(cell.clone().jam(), jammed_cell);
649 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
650 }
651
652 {
665 let cell: Noun = Noun::from(Cell::from([
666 Noun::from(Cell::from(["x-cached", "HIT"])),
667 Noun::from(Cell::from(["vary", "Origin"])),
668 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
669 Noun::from(Cell::from(["connection", "keep-alive"])),
670 Noun::from(Cell::from(["content-length", "59"])),
671 Noun::from(Cell::from(["content-type", "application/json"])),
672 Noun::from(Cell::from(["date", "Fri, 08 Jul 2022 16:43:50 GMT"])),
673 Noun::from(Atom::from(0u8)),
674 ]));
675
676 let jammed_cell = Atom::from(vec![
677 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
678 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
679 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 185, 0, 62, 99, 111, 110, 110, 101,
680 99, 116, 105, 111, 110, 128, 207, 90, 89, 25, 92, 75, 24, 91, 154, 93, 185, 0, 190,
681 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 208, 53, 121,
682 1, 252, 198, 222, 220, 232, 202, 220, 232, 90, 232, 242, 224, 202, 0, 255, 48, 56,
683 56, 182, 180, 177, 48, 186, 180, 55, 183, 23, 181, 185, 55, 119, 1, 159, 44, 140,
684 174, 12, 224, 217, 72, 46, 141, 5, 4, 6, 7, 68, 169, 142, 13, 68, 6, 70, 70, 6, 36,
685 198, 70, 135, 102, 70, 167, 6, 6, 228, 168, 137, 42,
686 ]);
687 assert_eq!(cell.clone().jam(), jammed_cell);
688 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
689 }
690
691 {
694 let cell: Noun = Noun::from(Cell::from(["server", "nginx/1.14.0 (Ubuntu)"]));
695 let jammed_cell = Atom::from(vec![
696 1, 190, 185, 50, 57, 187, 50, 57, 128, 38, 183, 179, 52, 55, 188, 151, 24, 151, 24,
697 26, 23, 24, 16, 148, 42, 177, 58, 55, 186, 186, 20,
698 ]);
699 assert_eq!(cell.clone().jam(), jammed_cell);
700 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
701 }
702
703 {
718 let cell: Noun = Noun::from(Cell::from([
719 Noun::from(Cell::from(["x-cached", "HIT"])),
720 Noun::from(Cell::from(["vary", "Origin"])),
721 Noun::from(Cell::from(["vary", "Accept-Encoding"])),
722 Noun::from(Cell::from(["connection", "keep-alive"])),
723 Noun::from(Cell::from(["content-length", "59"])),
724 Noun::from(Cell::from(["content-type", "application/json"])),
725 Noun::from(Cell::from(["date", "Fri, 08 Jul 2022 16:43:50 GMT"])),
726 Noun::from(Cell::from(["server", "nginx/1.14.0 (Ubuntu)"])),
727 Noun::from(Atom::from(0u8)),
728 ]));
729 let jammed_cell = Atom::from(vec![
730 5, 248, 241, 90, 198, 194, 198, 208, 202, 200, 192, 67, 74, 162, 22, 240, 237, 194,
731 228, 242, 128, 239, 73, 46, 237, 44, 205, 93, 227, 118, 128, 119, 208, 216, 88, 25,
732 28, 93, 75, 145, 219, 216, 27, 89, 154, 219, 185, 0, 62, 99, 111, 110, 110, 101,
733 99, 116, 105, 111, 110, 128, 207, 90, 89, 25, 92, 75, 24, 91, 154, 93, 185, 0, 190,
734 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 208, 53, 121,
735 1, 252, 198, 222, 220, 232, 202, 220, 232, 90, 232, 242, 224, 202, 0, 255, 48, 56,
736 56, 182, 180, 177, 48, 186, 180, 55, 183, 23, 181, 185, 55, 119, 1, 159, 44, 140,
737 174, 12, 224, 217, 72, 46, 141, 5, 4, 6, 7, 68, 169, 142, 13, 68, 6, 70, 70, 6, 36,
738 198, 70, 135, 102, 70, 167, 6, 6, 228, 168, 137, 90, 128, 111, 174, 76, 206, 174,
739 76, 14, 160, 201, 237, 44, 205, 13, 239, 37, 198, 37, 134, 198, 5, 6, 4, 165, 74,
740 172, 206, 141, 174, 46, 21,
741 ]);
742 assert_eq!(cell.clone().clone().jam(), jammed_cell);
743 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
744 }
745
746 {
761 let cell: Noun = Noun::from(Cell::from([
762 Noun::from(Atom::from("request")),
763 Noun::from(Atom::from(0u8)),
764 Noun::from(Atom::from("POST")),
765 Noun::from(Atom::from("http://eth-mainnet.urbit.org:8545")),
766 Noun::from(Cell::from([
767 Noun::from(Cell::from([
768 Atom::from("Content-Type"),
769 Atom::from("application/json"),
770 ])),
771 Noun::from(Atom::from(0u8)),
772 ])),
773 Noun::from(Atom::from(0u8)),
774 Noun::from(Atom::from(78u8)),
775 Noun::from(Atom::from(
776 r#"[{"params":[],"id":"block number","jsonrpc":"2.0","method":"eth_blockNumber"}]"#,
777 )),
778 ]));
779 let jammed_cell = Atom::from(vec![
780 1, 94, 185, 178, 184, 186, 178, 57, 122, 6, 124, 168, 167, 41, 106, 0, 52, 64, 163,
781 163, 131, 211, 121, 121, 41, 163, 67, 107, 105, 11, 75, 115, 115, 43, 163, 115,
782 169, 147, 19, 75, 163, 115, 121, 147, 59, 211, 193, 169, 161, 169, 43, 128, 223,
783 208, 155, 27, 93, 153, 27, 93, 11, 85, 30, 92, 25, 224, 31, 6, 7, 199, 150, 54, 22,
784 70, 151, 246, 230, 246, 162, 54, 247, 230, 54, 131, 59, 1, 240, 205, 214, 158, 8,
785 92, 152, 92, 88, 219, 156, 136, 206, 86, 23, 139, 72, 26, 153, 136, 142, 136, 24,
786 219, 219, 216, 26, 136, 91, 93, 155, 88, 153, 156, 8, 139, 136, 218, 220, 155, 155,
787 28, 220, 152, 136, 142, 136, 140, 11, 140, 8, 139, 72, 91, 25, 29, 218, 27, 153,
788 136, 142, 72, 25, 29, 218, 151, 24, 219, 219, 216, 154, 83, 93, 155, 88, 153, 156,
789 72, 95, 23,
790 ]);
791 assert_eq!(cell.clone().clone().jam(), jammed_cell);
792 assert_eq!(Noun::cue(jammed_cell).expect("cue"), cell);
793 }
794 }
795}