1use crate::chunk::ChunkParams;
5use serde::{Deserialize, Serialize};
6use serde_bytes::ByteBuf;
7
8fn bytebuf_is_empty(b: &ByteBuf) -> bool {
9 b.as_ref().is_empty()
10}
11
12fn is_zero_u8(x: &u8) -> bool {
13 *x == 0
14}
15
16#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct ChunkRef {
18 pub h: ByteBuf,
20 pub s: u32,
21 #[serde(default, skip_serializing_if = "is_zero_u8")]
23 pub x: u8,
24}
25
26#[derive(Clone, Debug, Serialize, Deserialize)]
28pub struct RefArchive {
29 pub root: ByteBuf,
31 pub hint: String,
33 pub chunks: u32,
35 pub bytes: u64,
36}
37
38#[derive(Clone, Debug, Serialize, Deserialize)]
39pub struct BlobRecord {
40 pub off: u64,
42 pub clen: u32,
43 pub ulen: u32,
44 pub codec: u8,
45 pub n: Vec<u32>,
47 #[serde(default, skip_serializing_if = "Vec::is_empty")]
49 pub p: Vec<u32>,
50 #[serde(default, skip_serializing_if = "is_zero_u8")]
53 pub f: u8,
54 #[serde(default, skip_serializing_if = "Vec::is_empty")]
57 pub d: Vec<u32>,
58}
59
60#[derive(Clone, Debug, Serialize, Deserialize, Default)]
61pub struct ChunkIndex {
62 pub chunks: Vec<ChunkRef>,
63 pub blobs: Vec<BlobRecord>,
64}
65
66#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
67pub struct Limits {
68 pub max_total: u64,
69 pub max_entry: u64,
70 pub max_ratio: u32,
71}
72
73impl Default for Limits {
74 fn default() -> Self {
75 Self { max_total: 4 << 30, max_entry: 1 << 30, max_ratio: 1000 }
76 }
77}
78
79#[derive(Clone, Debug, Serialize, Deserialize)]
80pub struct ZipMemberMeta {
81 pub name: String,
82 pub kind: u8,
84 pub local_header: ByteBuf,
86 #[serde(default, skip_serializing_if = "bytebuf_is_empty")]
88 pub descriptor: ByteBuf,
89 pub central: ByteBuf,
91 #[serde(default, skip_serializing_if = "bytebuf_is_empty")]
93 pub corrections: ByteBuf,
94 pub size: u64,
96 pub chunks: Vec<u32>,
97}
98
99#[derive(Clone, Debug, Serialize, Deserialize)]
100pub struct ZipRecipe {
101 pub local_order: Vec<u32>,
103 pub eocd: ByteBuf,
105 pub members: Vec<ZipMemberMeta>,
106}
107
108#[derive(Clone, Debug, Serialize, Deserialize)]
110pub struct StreamSegment {
111 pub kind: u8,
113 #[serde(default, skip_serializing_if = "bytebuf_is_empty")]
115 pub header: ByteBuf,
116 #[serde(default, skip_serializing_if = "bytebuf_is_empty")]
118 pub trailer: ByteBuf,
119 #[serde(default, skip_serializing_if = "bytebuf_is_empty")]
120 pub corrections: ByteBuf,
121 pub size: u64,
123 pub chunks: Vec<u32>,
124}
125
126#[derive(Clone, Debug, Serialize, Deserialize)]
127pub struct StreamRecipe {
128 pub segments: Vec<StreamSegment>,
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize)]
134pub struct Derived {
135 pub from: String,
137 pub view: String,
139 pub generator: String,
141 pub tokens_est: u64,
143}
144
145#[derive(Clone, Debug, Serialize, Deserialize)]
146pub struct Entry {
147 pub path: String,
148 pub size: u64,
149 pub h: ByteBuf,
151 pub mode: String,
153 #[serde(default)]
154 pub chunks: Vec<u32>,
155 #[serde(default, skip_serializing_if = "Option::is_none")]
156 pub mtime: Option<i64>,
157 #[serde(default, skip_serializing_if = "Option::is_none")]
158 pub zip: Option<ZipRecipe>,
159 #[serde(default, skip_serializing_if = "Option::is_none")]
160 pub streams: Option<StreamRecipe>,
161 #[serde(default, skip_serializing_if = "Option::is_none")]
162 pub note: Option<String>,
163 #[serde(default, skip_serializing_if = "Option::is_none")]
165 pub derived: Option<Derived>,
166}
167
168#[derive(Clone, Debug, Serialize, Deserialize)]
169pub struct Manifest {
170 pub tsaur: u16,
171 pub profile: String,
172 pub fidelity: String,
173 pub chunking: ChunkParams,
174 pub solid_block: u32,
175 pub limits: Limits,
176 pub root: ByteBuf,
178 pub entries: Vec<Entry>,
179 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub created: Option<u64>,
181 #[serde(default)]
182 pub generator: String,
183 #[serde(default, skip_serializing_if = "Vec::is_empty")]
184 pub refs: Vec<RefArchive>,
185}