dsf_core/options/
mod.rs

1//! Options are used to support extension of protocol objects
2//! with DSF and application-specific optional fields.
3
4#[cfg(feature = "alloc")]
5use alloc::prelude::v1::*;
6
7use byteorder::{ByteOrder, NetworkEndian};
8
9use crate::base::{Encode, Parse};
10use crate::types::{
11    Address, AddressV4, AddressV6, DateTime, Id, ImmutableData, Ip, PublicKey, Signature, ID_LEN,
12    PUBLIC_KEY_LEN, SIGNATURE_LEN,
13};
14
15mod helpers;
16
17/// DSF defined options fields
18#[derive(PartialEq, Debug, Clone)]
19#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
20pub enum Options {
21    None,
22    PubKey(PubKey),
23    PeerId(PeerId),
24    PrevSig(PrevSig),
25    Kind(Kind),
26    Name(Name),
27
28    IPv4(AddressV4),
29    IPv6(AddressV6),
30
31    Issued(Issued),
32    Expiry(Expiry),
33    Limit(Limit),
34    Metadata(Metadata),
35}
36
37/// Generic list of options over generic buffers
38#[derive(PartialEq, Debug, Clone)]
39#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
40pub enum OptionsList<C: AsRef<[Options]>, E: ImmutableData> {
41    Cleartext(C),
42    Encrypted(E),
43    None,
44}
45
46#[derive(PartialEq, Debug, Clone)]
47#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
48pub enum OptionsError {
49    IO,
50    InvalidMetadata,
51    InvalidOptionLength,
52    InvalidOptionKind,
53    Unimplemented,
54}
55
56#[cfg(feature = "std")]
57impl From<std::io::Error> for OptionsError {
58    fn from(e: std::io::Error) -> OptionsError {
59        error!("io error: {}", e);
60        OptionsError::IO
61    }
62}
63
64pub struct OptionsIter<T> {
65    index: usize,
66    buff: T,
67}
68
69impl<T> OptionsIter<T>
70where
71    T: AsRef<[u8]>,
72{
73    pub(crate) fn new(buff: T) -> Self {
74        Self { index: 0, buff }
75    }
76}
77
78impl<T> Iterator for OptionsIter<T>
79where
80    T: AsRef<[u8]>,
81{
82    type Item = Options;
83
84    fn next(&mut self) -> Option<Options> {
85        // Fetch remaining data
86        let rem = &self.buff.as_ref()[self.index..];
87
88        // Short circuit if we're too short
89        if rem.len() < OPTION_HEADER_LEN {
90            return None;
91        }
92
93        let (o, n) = match Options::parse(&rem) {
94            Ok(v) => v,
95            Err(e) => {
96                error!("Option parsing error: {:?}", e);
97                return None;
98            }
99        };
100
101        self.index += n;
102
103        Some(o)
104    }
105}
106
107/// D-IoT Option kind identifiers
108pub mod option_kinds {
109    pub const PUBKEY: u16 = 0x0000; // Public Key
110    pub const PEER_ID: u16 = 0x0001; // ID of Peer responsible for secondary page
111    pub const PREV_SIG: u16 = 0x0002; // Previous object signature
112    pub const KIND: u16 = 0x0003; // Service KIND in utf-8
113    pub const NAME: u16 = 0x0004; // Service NAME in utf-8
114    pub const ADDR_IPV4: u16 = 0x0005; // IPv4 service address
115    pub const ADDR_IPV6: u16 = 0x0006; // IPv6 service address
116    pub const ISSUED: u16 = 0x0007; // ISSUED option defines object creation time
117    pub const EXPIRY: u16 = 0x0008; // EXPIRY option defines object expiry time
118    pub const LIMIT: u16 = 0x0009; // LIMIT option defines maximum number of objects to return
119    pub const META: u16 = 0x000a; // META option supports generic metadata key:value pairs
120
121    pub const APP: u16 = 0x8000; // APP flag indictates option is application specific and should not be parsed here
122}
123
124/// Option header length
125const OPTION_HEADER_LEN: usize = 4;
126
127impl Options {
128    /// Parse a bounded list of options into a vector
129    pub fn parse_vec(data: &[u8]) -> Result<(Vec<Options>, usize), OptionsError> {
130        let mut options = Vec::new();
131        let mut rem = &data[..];
132        let mut i = 0;
133
134        while rem.len() >= OPTION_HEADER_LEN {
135            let (o, n) = Options::parse(&rem)?;
136            i += n;
137
138            options.push(o);
139            rem = &data[i..];
140        }
141
142        Ok((options, i))
143    }
144
145    /// Encode a vector of options
146    pub fn encode_vec(options: &[Options], data: &mut [u8]) -> Result<usize, OptionsError> {
147        let mut i = 0;
148
149        for o in options.iter() {
150            i += o.encode(&mut data[i..])?;
151        }
152
153        Ok(i)
154    }
155}
156
157impl Options {
158    // Helper to generate name metadata
159    pub fn name(value: &str) -> Options {
160        Options::Name(Name::new(value))
161    }
162
163    pub fn kind(value: &str) -> Options {
164        Options::Kind(Kind::new(value))
165    }
166
167    pub fn prev_sig(value: &Signature) -> Options {
168        Options::PrevSig(PrevSig::new(value.clone()))
169    }
170
171    pub fn meta(key: &str, value: &str) -> Options {
172        Options::Metadata(Metadata::new(key, value))
173    }
174
175    pub fn issued<T: Into<DateTime>>(now: T) -> Options {
176        Options::Issued(Issued::new(now))
177    }
178
179    pub fn expiry<T: Into<DateTime>>(when: T) -> Options {
180        Options::Expiry(Expiry::new(when))
181    }
182
183    pub fn peer_id(id: Id) -> Options {
184        Options::PeerId(PeerId::new(id))
185    }
186
187    pub fn public_key(public_key: PublicKey) -> Options {
188        Options::PubKey(PubKey::new(public_key))
189    }
190
191    pub fn address<T: Into<Address>>(address: T) -> Options {
192        let addr: Address = address.into();
193
194        match addr.ip {
195            Ip::V4(ip) => Options::IPv4(AddressV4::new(ip, addr.port)),
196            Ip::V6(ip) => Options::IPv6(AddressV6::new(ip, addr.port)),
197        }
198    }
199
200    pub fn address_v4<T: Into<AddressV4>>(address: T) -> Options {
201        Options::IPv4(address.into())
202    }
203
204    pub fn address_v6<T: Into<AddressV6>>(address: T) -> Options {
205        Options::IPv6(address.into())
206    }
207
208    pub fn pub_key(public_key: PublicKey) -> Options {
209        Options::PubKey(PubKey::new(public_key))
210    }
211}
212
213/// Parse parses a control option from the given scope
214impl Parse for Options {
215    type Output = Options;
216    type Error = OptionsError;
217
218    fn parse<'a>(data: &'a [u8]) -> Result<(Self::Output, usize), Self::Error> {
219        if data.len() < OPTION_HEADER_LEN {
220            return Err(OptionsError::InvalidOptionLength);
221        }
222
223        let option_kind = NetworkEndian::read_u16(&data[0..2]);
224        let option_len = NetworkEndian::read_u16(&data[2..4]) as usize;
225
226        let d = &data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + option_len];
227
228        match option_kind {
229            option_kinds::PUBKEY => {
230                let (opt, n) = PubKey::parse(d)?;
231                Ok((Options::PubKey(opt), n + OPTION_HEADER_LEN))
232            }
233            option_kinds::PEER_ID => {
234                let (opt, n) = PeerId::parse(d)?;
235                Ok((Options::PeerId(opt), n + OPTION_HEADER_LEN))
236            }
237            option_kinds::PREV_SIG => {
238                let (opt, n) = PrevSig::parse(d)?;
239                Ok((Options::PrevSig(opt), n + OPTION_HEADER_LEN))
240            }
241            option_kinds::KIND => {
242                let (opt, n) = Kind::parse(d)?;
243                Ok((Options::Kind(opt), n + OPTION_HEADER_LEN))
244            }
245            option_kinds::NAME => {
246                let (opt, n) = Name::parse(d)?;
247                Ok((Options::Name(opt), n + OPTION_HEADER_LEN))
248            }
249            option_kinds::ADDR_IPV4 => {
250                let (opt, n) = AddressV4::parse(d)?;
251                Ok((Options::IPv4(opt), n + OPTION_HEADER_LEN))
252            }
253            option_kinds::ADDR_IPV6 => {
254                let (opt, n) = AddressV6::parse(d)?;
255                Ok((Options::IPv6(opt), n + OPTION_HEADER_LEN))
256            }
257            option_kinds::META => {
258                let (opt, n) = Metadata::parse(d)?;
259                Ok((Options::Metadata(opt), n + OPTION_HEADER_LEN))
260            }
261            option_kinds::ISSUED => {
262                let (opt, n) = Issued::parse(d)?;
263                Ok((Options::Issued(opt), n + OPTION_HEADER_LEN))
264            }
265            option_kinds::EXPIRY => {
266                let (opt, n) = Expiry::parse(d)?;
267                Ok((Options::Expiry(opt), n + OPTION_HEADER_LEN))
268            }
269            option_kinds::LIMIT => {
270                let (opt, n) = Limit::parse(d)?;
271                Ok((Options::Limit(opt), n + OPTION_HEADER_LEN))
272            }
273            _ => {
274                // Unrecognised option types (and None) are skipped
275                Ok((Options::None, OPTION_HEADER_LEN + option_len))
276            }
277        }
278    }
279}
280
281impl Encode for Options {
282    type Error = OptionsError;
283
284    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
285        match *self {
286            Options::PubKey(ref o) => Ok(o.encode(data)?),
287            Options::PeerId(ref o) => Ok(o.encode(data)?),
288            Options::PrevSig(ref o) => Ok(o.encode(data)?),
289            Options::Kind(ref o) => Ok(o.encode(data)?),
290            Options::Name(ref o) => Ok(o.encode(data)?),
291            Options::IPv4(ref o) => Ok(o.encode(data)?),
292            Options::IPv6(ref o) => Ok(o.encode(data)?),
293            Options::Metadata(ref o) => Ok(o.encode(data)?),
294            Options::Issued(ref o) => Ok(o.encode(data)?),
295            Options::Expiry(ref o) => Ok(o.encode(data)?),
296            Options::Limit(ref o) => Ok(o.encode(data)?),
297            _ => {
298                warn!("Option encoding not implemented for object {:?}", *self);
299                unimplemented!();
300            }
301        }
302    }
303}
304
305#[derive(PartialEq, Debug, Clone)]
306#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
307pub struct PubKey {
308    pub public_key: PublicKey,
309}
310
311impl PubKey {
312    pub fn new(public_key: PublicKey) -> PubKey {
313        PubKey { public_key }
314    }
315}
316
317impl Parse for PubKey {
318    type Output = PubKey;
319    type Error = OptionsError;
320
321    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
322        let mut public_key = [0u8; PUBLIC_KEY_LEN];
323        public_key.copy_from_slice(&data[..PUBLIC_KEY_LEN]);
324
325        Ok((
326            PubKey {
327                public_key: public_key.into(),
328            },
329            PUBLIC_KEY_LEN,
330        ))
331    }
332}
333
334impl Encode for PubKey {
335    type Error = OptionsError;
336
337    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
338        NetworkEndian::write_u16(&mut data[0..2], option_kinds::PUBKEY);
339        NetworkEndian::write_u16(&mut data[2..4], PUBLIC_KEY_LEN as u16);
340
341        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + PUBLIC_KEY_LEN]
342            .copy_from_slice(&self.public_key);
343
344        Ok(OPTION_HEADER_LEN + PUBLIC_KEY_LEN)
345    }
346}
347
348#[derive(PartialEq, Debug, Clone)]
349#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
350pub struct PeerId {
351    pub peer_id: Id,
352}
353
354impl PeerId {
355    pub fn new(peer_id: Id) -> PeerId {
356        PeerId { peer_id }
357    }
358}
359
360impl Parse for PeerId {
361    type Output = PeerId;
362    type Error = OptionsError;
363
364    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
365        let mut peer_id = [0u8; ID_LEN];
366        peer_id.copy_from_slice(&data[..ID_LEN]);
367        Ok((
368            PeerId {
369                peer_id: peer_id.into(),
370            },
371            ID_LEN,
372        ))
373    }
374}
375
376impl Encode for PeerId {
377    type Error = OptionsError;
378
379    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
380        NetworkEndian::write_u16(&mut data[0..2], option_kinds::PEER_ID);
381        NetworkEndian::write_u16(&mut data[2..4], ID_LEN as u16);
382
383        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + ID_LEN].copy_from_slice(&self.peer_id);
384
385        Ok(OPTION_HEADER_LEN + ID_LEN)
386    }
387}
388
389#[derive(PartialEq, Debug, Clone)]
390#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
391pub struct PrevSig {
392    pub sig: Signature,
393}
394
395impl PrevSig {
396    pub fn new(sig: Signature) -> Self {
397        Self { sig }
398    }
399}
400
401impl Parse for PrevSig {
402    type Output = Self;
403    type Error = OptionsError;
404
405    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
406        let mut sig = [0u8; SIGNATURE_LEN];
407        sig.copy_from_slice(&data[..SIGNATURE_LEN]);
408        Ok((Self { sig: sig.into() }, SIGNATURE_LEN))
409    }
410}
411
412impl Encode for PrevSig {
413    type Error = OptionsError;
414
415    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
416        NetworkEndian::write_u16(&mut data[0..2], option_kinds::PREV_SIG);
417        NetworkEndian::write_u16(&mut data[2..4], SIGNATURE_LEN as u16);
418
419        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + SIGNATURE_LEN].copy_from_slice(&self.sig);
420
421        Ok(OPTION_HEADER_LEN + SIGNATURE_LEN)
422    }
423}
424
425#[derive(PartialEq, Debug, Clone)]
426#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
427pub struct Kind {
428    value: String,
429}
430
431impl Kind {
432    pub fn new(value: &str) -> Kind {
433        Kind {
434            value: value.to_owned(),
435        }
436    }
437}
438
439impl Parse for Kind {
440    type Output = Kind;
441    type Error = OptionsError;
442
443    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
444        let value = core::str::from_utf8(&data).unwrap().to_owned();
445
446        Ok((Kind { value }, data.len()))
447    }
448}
449
450impl Encode for Kind {
451    type Error = OptionsError;
452
453    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
454        let value = self.value.as_bytes();
455
456        NetworkEndian::write_u16(&mut data[0..2], option_kinds::KIND);
457        NetworkEndian::write_u16(&mut data[2..4], value.len() as u16);
458
459        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + value.len()].copy_from_slice(&value);
460
461        Ok(OPTION_HEADER_LEN + value.len())
462    }
463}
464
465#[derive(PartialEq, Debug, Clone)]
466#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
467pub struct Name {
468    value: String,
469}
470
471impl Name {
472    pub fn new(value: &str) -> Name {
473        Name {
474            value: value.to_owned(),
475        }
476    }
477}
478
479impl Parse for Name {
480    type Output = Name;
481    type Error = OptionsError;
482
483    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
484        let value = core::str::from_utf8(&data).unwrap().to_owned();
485
486        Ok((Name { value }, data.len()))
487    }
488}
489
490impl Encode for Name {
491    type Error = OptionsError;
492
493    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
494        NetworkEndian::write_u16(&mut data[0..2], option_kinds::NAME);
495        NetworkEndian::write_u16(&mut data[2..4], self.value.len() as u16);
496
497        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + self.value.len()]
498            .copy_from_slice(&self.value.as_bytes());
499
500        Ok(OPTION_HEADER_LEN + self.value.len())
501    }
502}
503
504impl Parse for AddressV4 {
505    type Output = AddressV4;
506    type Error = OptionsError;
507
508    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
509        let mut ip = [0u8; 4];
510
511        ip.copy_from_slice(&data[0..4]);
512        let port = NetworkEndian::read_u16(&data[4..6]);
513
514        Ok((AddressV4::new(ip, port), 6))
515    }
516}
517
518impl Encode for AddressV4 {
519    type Error = OptionsError;
520
521    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
522        NetworkEndian::write_u16(&mut data[0..2], option_kinds::ADDR_IPV4);
523        NetworkEndian::write_u16(&mut data[2..4], 6);
524
525        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + 4].copy_from_slice(&self.ip);
526        NetworkEndian::write_u16(&mut data[OPTION_HEADER_LEN + 4..], self.port);
527
528        Ok(OPTION_HEADER_LEN + 6)
529    }
530}
531
532impl Parse for AddressV6 {
533    type Output = AddressV6;
534    type Error = OptionsError;
535
536    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
537        let mut ip = [0u8; 16];
538
539        ip.copy_from_slice(&data[0..16]);
540        let port = NetworkEndian::read_u16(&data[16..18]);
541
542        Ok((AddressV6::new(ip, port), 18))
543    }
544}
545
546impl Encode for AddressV6 {
547    type Error = OptionsError;
548
549    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
550        NetworkEndian::write_u16(&mut data[0..2], option_kinds::ADDR_IPV6);
551        NetworkEndian::write_u16(&mut data[2..4], 18);
552
553        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + 16].copy_from_slice(&self.ip);
554        NetworkEndian::write_u16(&mut data[OPTION_HEADER_LEN + 16..], self.port);
555
556        Ok(OPTION_HEADER_LEN + 18)
557    }
558}
559
560#[derive(PartialEq, Debug, Clone)]
561#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
562pub struct Metadata {
563    key: String,
564    value: String,
565}
566
567impl Metadata {
568    pub fn new(key: &str, value: &str) -> Metadata {
569        Metadata {
570            key: key.to_owned(),
571            value: value.to_owned(),
572        }
573    }
574}
575
576impl Parse for Metadata {
577    type Output = Metadata;
578    type Error = OptionsError;
579
580    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
581        let kv = core::str::from_utf8(&data).unwrap().to_owned();
582        let split: Vec<_> = kv.split("|").collect();
583        if split.len() != 2 {
584            return Err(OptionsError::InvalidMetadata);
585        }
586
587        Ok((
588            Metadata {
589                key: split[0].to_owned(),
590                value: split[1].to_owned(),
591            },
592            data.len(),
593        ))
594    }
595}
596
597impl Encode for Metadata {
598    type Error = OptionsError;
599
600    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
601        let meta = format!("{}|{}", self.key, self.value);
602
603        NetworkEndian::write_u16(&mut data[0..2], option_kinds::META);
604        NetworkEndian::write_u16(&mut data[2..4], meta.len() as u16);
605
606        &mut data[OPTION_HEADER_LEN..OPTION_HEADER_LEN + meta.len()]
607            .copy_from_slice(meta.as_bytes());
608
609        Ok(OPTION_HEADER_LEN + meta.len())
610    }
611}
612
613impl From<Metadata> for Options {
614    fn from(m: Metadata) -> Options {
615        Options::Metadata(m)
616    }
617}
618
619#[derive(PartialEq, Debug, Clone)]
620#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
621pub struct Issued {
622    pub when: DateTime,
623}
624
625impl Issued {
626    pub fn new<T>(when: T) -> Issued
627    where
628        T: Into<DateTime>,
629    {
630        Issued { when: when.into() }
631    }
632}
633
634impl Parse for Issued {
635    type Output = Issued;
636    type Error = OptionsError;
637    fn parse<'a>(data: &'a [u8]) -> Result<(Self::Output, usize), Self::Error> {
638        let raw = NetworkEndian::read_u64(&data[0..8]);
639        let when = DateTime::from_secs(raw);
640
641        Ok((Issued { when }, 8))
642    }
643}
644
645impl Encode for Issued {
646    type Error = OptionsError;
647
648    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
649        NetworkEndian::write_u16(&mut data[0..2], option_kinds::ISSUED);
650        NetworkEndian::write_u16(&mut data[2..4], 8);
651
652        NetworkEndian::write_u64(&mut data[4..12], self.when.as_secs());
653
654        Ok(OPTION_HEADER_LEN + 8)
655    }
656}
657
658#[derive(PartialEq, Debug, Clone)]
659#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
660pub struct Expiry {
661    pub when: DateTime,
662}
663
664impl Expiry {
665    pub fn new<T>(when: T) -> Expiry
666    where
667        T: Into<DateTime>,
668    {
669        Expiry { when: when.into() }
670    }
671}
672
673impl Parse for Expiry {
674    type Output = Expiry;
675    type Error = OptionsError;
676    fn parse<'a>(data: &'a [u8]) -> Result<(Self::Output, usize), Self::Error> {
677        let raw = NetworkEndian::read_u64(&data[0..8]);
678        let when = DateTime::from_secs(raw);
679
680        Ok((Expiry { when }, 8))
681    }
682}
683
684impl Encode for Expiry {
685    type Error = OptionsError;
686    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
687        NetworkEndian::write_u16(&mut data[0..2], option_kinds::EXPIRY);
688        NetworkEndian::write_u16(&mut data[2..4], 8);
689
690        NetworkEndian::write_u64(&mut data[4..12], self.when.as_secs());
691
692        Ok(OPTION_HEADER_LEN + 8)
693    }
694}
695
696#[derive(PartialEq, Debug, Clone)]
697#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
698pub struct Limit {
699    pub n: u32,
700}
701
702impl Limit {
703    pub fn new(n: u32) -> Self {
704        Self { n }
705    }
706}
707
708impl Parse for Limit {
709    type Output = Self;
710    type Error = OptionsError;
711
712    fn parse(data: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
713        Ok((
714            Self {
715                n: NetworkEndian::read_u32(data),
716            },
717            4,
718        ))
719    }
720}
721
722impl Encode for Limit {
723    type Error = OptionsError;
724
725    fn encode(&self, data: &mut [u8]) -> Result<usize, Self::Error> {
726        NetworkEndian::write_u16(&mut data[0..2], option_kinds::LIMIT);
727        NetworkEndian::write_u16(&mut data[2..4], 4);
728        NetworkEndian::write_u32(&mut data[4..8], self.n);
729
730        Ok(8)
731    }
732}
733
734#[cfg(test)]
735mod tests {
736
737    use super::*;
738
739    use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
740    use std::time::SystemTime;
741
742    #[test]
743    fn encode_decode_option_types() {
744        let tests = [
745            Options::PubKey(PubKey::new([1u8; PUBLIC_KEY_LEN].into())),
746            Options::PeerId(PeerId::new([2u8; ID_LEN].into())),
747            Options::Kind(Kind::new("test-kind")),
748            Options::Name(Name::new("test-name")),
749            Options::address_v4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)),
750            Options::address_v6(SocketAddrV6::new(
751                Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1),
752                8080,
753                0,
754                0,
755            )),
756            Options::Metadata(Metadata::new("test-key", "test-value")),
757            Options::issued(SystemTime::now()),
758            Options::expiry(SystemTime::now()),
759            Options::Limit(Limit::new(13)),
760        ];
761
762        for o in tests.iter() {
763            println!("Encode/Decode: {:?}", o);
764
765            let mut data = vec![0u8; 1024];
766            let n1 = o
767                .encode(&mut data)
768                .expect(&format!("Error encoding {:?}", o));
769
770            let (decoded, n2) = Options::parse(&data).expect(&format!("Error decoding {:?}", o));
771
772            assert_eq!(
773                n1, n2,
774                "Mismatch between encoded and decoded lengths for object: {:?}",
775                o
776            );
777            assert_eq!(o, &decoded, "Mismatch between original and decode objects");
778        }
779    }
780
781    #[test]
782    fn encode_decode_option_list() {
783        let tests = vec![
784            Options::PubKey(PubKey::new([1u8; PUBLIC_KEY_LEN].into())),
785            Options::PeerId(PeerId::new([2u8; ID_LEN].into())),
786            Options::PrevSig(PrevSig::new([3u8; SIGNATURE_LEN].into())),
787            Options::Kind(Kind::new("test-kind")),
788            Options::Name(Name::new("test-name")),
789            Options::address_v4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)),
790            Options::address_v6(SocketAddrV6::new(
791                Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1),
792                8080,
793                0,
794                0,
795            )),
796            Options::Metadata(Metadata::new("test-key", "test-value")),
797            Options::issued(SystemTime::now()),
798            Options::expiry(SystemTime::now()),
799        ];
800
801        let mut data = vec![0u8; 1024];
802        let n1 = Options::encode_vec(&tests, &mut data).expect("Error encoding options vector");
803
804        let encoded = &data[0..n1];
805        let (decoded, n2) = Options::parse_vec(encoded).expect("Error decoding options vector");
806
807        assert_eq!(n1, n2, "Mismatch between encoded and decoded length");
808        assert_eq!(
809            &tests, &decoded,
810            "Mismatch between original and decode vectors"
811        );
812    }
813}