ssb_multiformats/
multifeed.rs

1use std::io::{self, Write};
2
3use super::multikey::{self, Multikey};
4
5/// A multifeed that owns its data.
6#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
7pub enum Multifeed {
8    Multikey(Multikey),
9}
10
11impl Multifeed {
12    /// Create a new multifeed of kind `multikey`.
13    pub fn from_multikey(mk: Multikey) -> Multifeed {
14        Multifeed::Multikey(mk)
15    }
16
17    /// Parses a
18    /// [legacy encoding](https://spec.scuttlebutt.nz/feed/datatypes.html#multifeed-legacy-encoding)
19    /// into a `Multifeed`, also returning the remaining input on success.
20    pub fn from_legacy(s: &[u8]) -> Result<(Multifeed, &[u8]), DecodeLegacyError> {
21        if s.is_empty() {
22            return Err(DecodeLegacyError::UnknownKind);
23        }
24
25        match s[0] {
26            0x40 => {
27                let (mk, tail) = Multikey::from_legacy(s)?;
28                Ok((Multifeed::from_multikey(mk), tail))
29            }
30            _ => Err(DecodeLegacyError::UnknownKind),
31        }
32    }
33
34    /// Serialize a `Multifeed` into a writer, using the
35    /// [legacy encoding](https://spec.scuttlebutt.nz/feed/datatypes.html#multifeed-legacy-encoding).
36    pub fn to_legacy<W: Write>(&self, w: &mut W) -> Result<(), io::Error> {
37        match self {
38            Multifeed::Multikey(ref mk) => mk.to_legacy(w),
39        }
40    }
41
42    /// Serialize a `Multifeed` into an owned byte vector, using the
43    /// [legacy encoding](https://spec.scuttlebutt.nz/feed/datatypes.html#multifeed-legacy-encoding).
44    pub fn to_legacy_vec(&self) -> Vec<u8> {
45        match self {
46            Multifeed::Multikey(ref mk) => mk.to_legacy_vec(),
47        }
48    }
49
50    /// Serialize a `Multifeed` into an owned string, using the
51    /// [legacy encoding](https://spec.scuttlebutt.nz/feed/datatypes.html#multifeed-legacy-encoding).
52    pub fn to_legacy_string(&self) -> String {
53        unsafe { String::from_utf8_unchecked(self.to_legacy_vec()) }
54    }
55}
56
57/// Everything that can go wrong when decoding a `Multikey` from the legacy encoding.
58#[derive(Debug, PartialEq, Eq, Clone)]
59pub enum DecodeLegacyError {
60    /// Input did not start with the `"@"` sigil.
61    UnknownKind,
62    /// Decoding the inner multikey failed.
63    Multikey(multikey::DecodeLegacyError),
64}
65
66impl From<multikey::DecodeLegacyError> for DecodeLegacyError {
67    fn from(err: multikey::DecodeLegacyError) -> DecodeLegacyError {
68        DecodeLegacyError::Multikey(err)
69    }
70}