1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::builder::Builder;
use crate::decoder;
use crate::encoder;
use crate::prelude::*;
pub use http::Uri;
use std::convert::TryFrom;
use std::io::Write;
pub type Body = Vec<u8>;
pub type Request = http::Request<()>;
pub type Response = http::Response<Body>;
pub const HEADER_MAGIC_BYTES: [u8; 8] = [0xf0, 0x9f, 0x8c, 0x90, 0xf0, 0x9f, 0x93, 0xa6];
pub(crate) const VERSION_BYTES_LEN: usize = 4;
pub(crate) const TOP_ARRAY_LEN: usize = 6;
pub(crate) const KNOWN_SECTION_NAMES: [&str; 5] =
["index", "manifest", "signatures", "critical", "responses"];
#[derive(Debug, PartialEq, Eq)]
pub enum Version {
VersionB1,
Version1,
Unknown([u8; 4]),
}
impl Version {
pub fn bytes(&self) -> &[u8; 4] {
match self {
Version::VersionB1 => &[0x62, 0x31, 0, 0],
Version::Version1 => &[0x31, 0, 0, 0],
Version::Unknown(a) => &a,
}
}
}
#[derive(Debug)]
pub struct Exchange {
pub request: Request,
pub response: Response,
}
#[derive(Debug)]
pub struct Bundle {
pub(crate) version: Version,
pub(crate) primary_url: Uri,
pub(crate) manifest: Option<Uri>,
pub(crate) exchanges: Vec<Exchange>,
}
impl Bundle {
pub fn version(&self) -> &Version {
&self.version
}
pub fn primary_url(&self) -> &Uri {
&self.primary_url
}
pub fn manifest(&self) -> &Option<Uri> {
&self.manifest
}
pub fn exchanges(&self) -> &[Exchange] {
&self.exchanges
}
pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Bundle> {
decoder::parse(bytes)
}
pub fn write_to<W: Write + Sized>(&self, write: W) -> Result<()> {
encoder::encode(&self, write)
}
pub fn encode(&self) -> Result<Vec<u8>> {
encoder::encode_to_vec(&self)
}
pub fn builder() -> Builder {
Builder::new()
}
}
impl<'a> TryFrom<&'a [u8]> for Bundle {
type Error = anyhow::Error;
fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
Bundle::from_bytes(bytes)
}
}