rez_next_package/serialization/
types.rs1use crate::Package;
4use chrono::Utc;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::path::Path;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum PackageFormat {
12 Yaml,
14 Json,
16 Python,
18 YamlCompressed,
20 JsonCompressed,
22 Binary,
24
25 Toml,
27 Xml,
29}
30
31#[derive(Debug, Clone)]
33pub struct SerializationOptions {
34 pub pretty_print: bool,
36 pub include_metadata: bool,
38 pub include_timestamps: bool,
40 pub compression_level: u32,
42 pub field_filters: Vec<String>,
44 pub include_only: Option<Vec<String>>,
46 pub exclude_fields: Option<Vec<String>>,
48 pub custom_rules: HashMap<String, String>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct PackageMetadata {
55 pub serialized_at: String,
57 pub format: String,
59 pub serializer_version: String,
61 pub original_path: Option<String>,
63 pub checksum: Option<String>,
65 pub custom: HashMap<String, String>,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct PackageContainer {
72 pub package: Package,
74 pub metadata: PackageMetadata,
76 pub schema_version: String,
78}
79
80impl PackageFormat {
83 pub fn from_extension(path: &Path) -> Option<Self> {
85 let path_str = path.to_string_lossy();
86
87 if path_str.ends_with(".yaml.gz") || path_str.ends_with(".yml.gz") {
88 return Some(Self::YamlCompressed);
89 }
90 if path_str.ends_with(".json.gz") {
91 return Some(Self::JsonCompressed);
92 }
93
94 match path.extension()?.to_str()? {
95 "yaml" | "yml" => Some(Self::Yaml),
96 "json" => Some(Self::Json),
97 "py" => Some(Self::Python),
98 "bin" => Some(Self::Binary),
99 "toml" => Some(Self::Toml),
100 "xml" => Some(Self::Xml),
101 _ => None,
102 }
103 }
104
105 pub fn default_filename(&self) -> &'static str {
107 match self {
108 Self::Yaml => "package.yaml",
109 Self::Json => "package.json",
110 Self::Python => "package.py",
111 Self::YamlCompressed => "package.yaml.gz",
112 Self::JsonCompressed => "package.json.gz",
113 Self::Binary => "package.bin",
114 Self::Toml => "package.toml",
115 Self::Xml => "package.xml",
116 }
117 }
118
119 pub fn supports_compression(&self) -> bool {
121 matches!(self, Self::YamlCompressed | Self::JsonCompressed)
122 }
123
124 pub fn is_text_format(&self) -> bool {
126 !matches!(self, Self::Binary)
127 }
128
129 pub fn mime_type(&self) -> &'static str {
131 match self {
132 Self::Yaml | Self::YamlCompressed => "application/x-yaml",
133 Self::Json | Self::JsonCompressed => "application/json",
134 Self::Python => "text/x-python",
135 Self::Binary => "application/octet-stream",
136 Self::Toml => "application/toml",
137 Self::Xml => "application/xml",
138 }
139 }
140}
141
142impl SerializationOptions {
145 pub fn new() -> Self {
147 Self {
148 pretty_print: true,
149 include_metadata: true,
150 include_timestamps: true,
151 compression_level: 6,
152 field_filters: Vec::new(),
153 include_only: None,
154 exclude_fields: None,
155 custom_rules: HashMap::new(),
156 }
157 }
158
159 pub fn minimal() -> Self {
161 Self {
162 pretty_print: false,
163 include_metadata: false,
164 include_timestamps: false,
165 compression_level: 1,
166 field_filters: Vec::new(),
167 include_only: None,
168 exclude_fields: None,
169 custom_rules: HashMap::new(),
170 }
171 }
172
173 pub fn compact() -> Self {
175 Self {
176 pretty_print: false,
177 include_metadata: true,
178 include_timestamps: false,
179 compression_level: 9,
180 field_filters: Vec::new(),
181 include_only: None,
182 exclude_fields: Some(vec!["description".to_string(), "help".to_string()]),
183 custom_rules: HashMap::new(),
184 }
185 }
186
187 pub fn add_field_filter(&mut self, filter: String) {
189 self.field_filters.push(filter);
190 }
191
192 pub fn set_include_only(&mut self, fields: Vec<String>) {
194 self.include_only = Some(fields);
195 }
196
197 pub fn set_exclude_fields(&mut self, fields: Vec<String>) {
199 self.exclude_fields = Some(fields);
200 }
201
202 pub fn add_custom_rule(&mut self, field: String, rule: String) {
204 self.custom_rules.insert(field, rule);
205 }
206}
207
208impl Default for SerializationOptions {
209 fn default() -> Self {
210 Self::new()
211 }
212}
213
214impl PackageMetadata {
217 pub fn new(format: String) -> Self {
219 Self {
220 serialized_at: Utc::now().to_rfc3339(),
221 format,
222 serializer_version: env!("CARGO_PKG_VERSION").to_string(),
223 original_path: None,
224 checksum: None,
225 custom: HashMap::new(),
226 }
227 }
228
229 pub fn set_original_path(&mut self, path: String) {
231 self.original_path = Some(path);
232 }
233
234 pub fn set_checksum(&mut self, checksum: String) {
236 self.checksum = Some(checksum);
237 }
238
239 pub fn add_custom(&mut self, key: String, value: String) {
241 self.custom.insert(key, value);
242 }
243}
244
245impl PackageContainer {
248 pub fn new(package: Package, format: String) -> Self {
250 Self {
251 package,
252 metadata: PackageMetadata::new(format),
253 schema_version: "1.0".to_string(),
254 }
255 }
256
257 pub fn with_metadata(package: Package, metadata: PackageMetadata) -> Self {
259 Self {
260 package,
261 metadata,
262 schema_version: "1.0".to_string(),
263 }
264 }
265}