1use std::{borrow::Cow, path::PathBuf};
2
3use serde::{de::Visitor, Deserializer};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7pub(crate) mod internal;
8pub mod ip;
9pub mod utils;
10
11pub use ip::Ip;
12
13use crate::utils::time::Filetime;
14
15pub type Text = Cow<'static, str>;
16
17#[derive(Clone, Default)]
18#[non_exhaustive]
19pub enum Field {
20 #[default]
21 Null,
22 Text(Text),
24 Ip(Ip),
26 Domain(String),
28 User(String),
29 AssetID(String),
40 U64(u64),
42 I64(i64),
44 F64(f64),
46 Date(Filetime),
48 Array(Vec<Text>),
49 Path(PathBuf),
50}
51
52impl std::fmt::Debug for Field {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 match self {
55 Self::Null => write!(f, "Null"),
56 Self::Text(arg0) => f.write_fmt(format_args!("{:?}", arg0)),
57 Self::Ip(arg0) => f.write_fmt(format_args!("{}", arg0)),
58 Self::Domain(arg0) => f.write_fmt(format_args!("{:?}", arg0)),
59 Self::User(arg0) => f.write_fmt(format_args!("{:?}", arg0)),
60 Self::AssetID(arg0) => f.write_fmt(format_args!("{:?}", arg0)),
61 Self::U64(arg0) => f.write_fmt(format_args!("{}", arg0)),
62 Self::I64(arg0) => f.write_fmt(format_args!("{}", arg0)),
63 Self::F64(arg0) => f.write_fmt(format_args!("{}", arg0)),
64 Self::Date(arg0) => f.write_fmt(format_args!("{:?}", arg0)),
65 Self::Array(arg0) => f.debug_list().entries(arg0.iter()).finish(),
66 Self::Path(arg0) => f.write_fmt(format_args!("{:?}", arg0.to_string_lossy())),
67 }
68 }
69}
70
71impl<'a> TryInto<&'a str> for &'a Field {
72 type Error = &'static str;
73
74 fn try_into(self) -> Result<&'a str, Self::Error> {
75 match self {
76 Field::Text(v) => Ok(&v[..]),
77 Field::Domain(v) => Ok(&v[..]),
78 Field::User(v) => Ok(&v[..]),
79 Field::AssetID(v) => Ok(&v[..]),
80 _ => Err("Invalid text type"),
81 }
82 }
83}
84
85impl<'a> TryInto<Text> for &'a Field {
86 type Error = &'static str;
87
88 fn try_into(self) -> Result<Text, Self::Error> {
89 match self {
90 Field::Text(v) => Ok(v.clone()),
91 Field::Domain(v) => Ok(Text::Owned(v.to_string())),
92 Field::User(v) => Ok(Text::Owned(v.to_string())),
93 Field::AssetID(v) => Ok(Text::Owned(v.to_string())),
94 _ => Err("Invalid type"),
95 }
96 }
97}
98impl<'a> TryInto<&'a Text> for &'a Field {
99 type Error = &'static str;
100
101 fn try_into(self) -> Result<&'a Text, Self::Error> {
102 match self {
103 Field::Text(v) => Ok(v),
104 _ => Err("Invalid type"),
105 }
106 }
107}
108
109impl<'a> TryInto<&'a Vec<Text>> for &'a Field {
110 type Error = &'static str;
111
112 fn try_into(self) -> Result<&'a Vec<Text>, Self::Error> {
113 match self {
114 Field::Array(v) => Ok(v),
115 _ => Err("Invalid type"),
116 }
117 }
118}
119
120impl<'a> TryInto<Vec<Text>> for &'a Field {
121 type Error = &'static str;
122
123 fn try_into(self) -> Result<Vec<Text>, Self::Error> {
124 let value = match self {
125 Field::Array(v) => return Ok(v.clone()),
126 Field::AssetID(v) => Text::Owned(v.clone()),
127 Field::Text(v) => v.clone(),
128 Field::Domain(v) => Text::Owned(v.clone()),
129 Field::User(v) => Text::Owned(v.clone()),
130 Field::I64(v) => Text::Owned(v.to_string()),
131 Field::F64(v) => Text::Owned(v.to_string()),
132 Field::U64(v) => Text::Owned(v.to_string()),
133 Field::Date(v) => Text::Owned(v.to_string()),
134 Field::Ip(v) => Text::Owned(v.to_string()),
135 Field::Null => Text::Borrowed(""),
136 Field::Path(v) => Text::Owned(v.to_string_lossy().to_string()),
137 };
138 Ok(vec![value])
139 }
140}
141
142impl<'a> TryInto<u64> for &'a Field {
143 type Error = &'static str;
144
145 fn try_into(self) -> Result<u64, Self::Error> {
146 Ok(match self {
147 Field::F64(v) => *v as u64,
148 Field::I64(v) => *v as u64,
149 Field::U64(v) => *v,
150 Field::Date(v) => v.filetime(),
151 _ => return Err("Invalid type"),
152 })
153 }
154}
155impl<'a> TryInto<i64> for &'a Field {
156 type Error = &'static str;
157
158 fn try_into(self) -> Result<i64, Self::Error> {
159 Ok(match self {
160 Field::F64(v) => *v as i64,
161 Field::I64(v) => *v,
162 Field::U64(v) => *v as i64,
163 Field::Date(v) => v.filetime() as i64,
164 _ => return Err("Invalid type"),
165 })
166 }
167}
168impl<'a> TryInto<f64> for &'a Field {
169 type Error = &'static str;
170
171 fn try_into(self) -> Result<f64, Self::Error> {
172 Ok(match self {
173 Field::F64(v) => *v,
174 Field::I64(v) => *v as f64,
175 Field::U64(v) => *v as f64,
176 Field::Date(v) => v.filetime() as f64,
177 _ => return Err("Invalid type"),
178 })
179 }
180}
181
182impl<'a> TryInto<Ip> for &'a Field {
183 type Error = &'static str;
184 fn try_into(self) -> Result<Ip, Self::Error> {
185 Ok(match self {
186 Field::Text(v) => Ip::from_ip_str(v).map_err(|_e| "Invalud ip format")?,
187 Field::Ip(v) => *v,
188 _ => return Err("Type cannot be converted to Ip"),
189 })
190 }
191}
192
193impl From<&'static str> for Field {
194 fn from(v: &'static str) -> Field {
195 Field::Text(Text::Borrowed(v))
196 }
197}
198impl From<&String> for Field {
199 fn from(v: &String) -> Field {
200 Field::Text(Text::Owned(v.to_string()))
201 }
202}
203impl From<String> for Field {
204 fn from(v: String) -> Field {
205 Field::Text(Text::Owned(v))
206 }
207}
208impl From<Text> for Field {
209 fn from(v: Text) -> Field {
210 Field::Text(v)
211 }
212}
213impl From<&Text> for Field {
214 fn from(v: &Text) -> Field {
215 Field::Text(v.clone())
216 }
217}
218
219impl From<&u64> for Field {
220 fn from(v: &u64) -> Field {
221 Field::U64(*v)
222 }
223}
224impl From<u64> for Field {
225 fn from(v: u64) -> Field {
226 Field::U64(v)
227 }
228}
229impl From<&u32> for Field {
230 fn from(v: &u32) -> Field {
231 Field::U64(*v as u64)
232 }
233}
234impl From<u32> for Field {
235 fn from(v: u32) -> Field {
236 Field::U64(v as u64)
237 }
238}
239
240impl From<&i64> for Field {
241 fn from(v: &i64) -> Field {
242 Field::I64(*v)
243 }
244}
245impl From<i64> for Field {
246 fn from(v: i64) -> Field {
247 Field::I64(v)
248 }
249}
250
251impl From<&f64> for Field {
252 fn from(v: &f64) -> Field {
253 Field::F64(*v)
254 }
255}
256impl From<f64> for Field {
257 fn from(v: f64) -> Field {
258 Field::F64(v)
259 }
260}
261impl From<Ip> for Field {
262 fn from(v: Ip) -> Field {
263 Field::Ip(v)
264 }
265}
266impl From<&Ip> for Field {
267 fn from(v: &Ip) -> Field {
268 Field::Ip(*v)
269 }
270}
271impl From<Vec<Text>> for Field {
272 fn from(v: Vec<Text>) -> Field {
273 Field::Array(v)
274 }
275}
276impl From<&Vec<Text>> for Field {
277 fn from(v: &Vec<Text>) -> Field {
278 Field::Array(v.clone())
279 }
280}
281
282#[cfg(feature = "serde")]
283impl Serialize for Field {
284 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
285 where
286 S: serde::Serializer,
287 {
288 match self {
289 Field::Null => serializer.serialize_none(),
290 Field::Text(v) => serializer.serialize_str(&v[..]),
291 Field::Ip(v) => v.serialize(serializer),
292 Field::Domain(v) => serializer.serialize_str(&v[..]),
293 Field::User(v) => serializer.serialize_str(&v[..]),
294 Field::AssetID(v) => serializer.serialize_str(&v[..]),
295 Field::U64(v) => serializer.serialize_u64(*v),
296 Field::I64(v) => serializer.serialize_i64(*v),
297 Field::F64(v) => serializer.serialize_f64(*v),
298 Field::Date(v) => serializer.serialize_str(&v.to_string()),
299 Field::Array(v) => v.serialize(serializer),
300 Field::Path(v) => serializer.serialize_str(&v.to_string_lossy()[..]),
301 }
302 }
303}
304#[cfg(feature = "serde")]
305impl<'de> Deserialize<'de> for Field {
306 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
307 where
308 D: Deserializer<'de>,
309 {
310 deserializer.deserialize_any(FieldVisitor)
311 }
312}
313#[cfg(feature = "serde")]
314struct FieldVisitor;
315#[cfg(feature = "serde")]
316impl<'de> Visitor<'de> for FieldVisitor {
317 type Value = Field;
318
319 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
320 formatter.write_str("a valid forensic data")
321 }
322
323 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
324 where
325 E: serde::de::Error,
326 {
327 Ok(Field::Text(Cow::Owned(v.to_string())))
328 }
329 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
330 where
331 E: serde::de::Error,
332 {
333 Ok(Field::Text(Cow::Owned(v)))
334 }
335 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
336 where
337 E: serde::de::Error,
338 {
339 Ok(Field::U64(if v { 1 } else { 0 }))
340 }
341
342 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
343 where
344 E: serde::de::Error,
345 {
346 Ok(Field::I64(v as _))
347 }
348 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
349 where
350 E: serde::de::Error,
351 {
352 Ok(Field::I64(v as _))
353 }
354 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
355 where
356 E: serde::de::Error,
357 {
358 Ok(Field::I64(v as _))
359 }
360 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
361 where
362 E: serde::de::Error,
363 {
364 Ok(Field::I64(v))
365 }
366 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
367 where
368 E: serde::de::Error,
369 {
370 Ok(Field::F64(v as _))
371 }
372
373 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
374 where
375 E: serde::de::Error,
376 {
377 Ok(Field::F64(v))
378 }
379
380 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
381 where
382 E: serde::de::Error,
383 {
384 Ok(Field::U64(v as _))
385 }
386 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
387 where
388 E: serde::de::Error,
389 {
390 Ok(Field::U64(v))
391 }
392
393 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
394 where
395 E: serde::de::Error,
396 {
397 Ok(Field::U64(v as _))
398 }
399 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
400 where
401 E: serde::de::Error,
402 {
403 Ok(Field::U64(v as _))
404 }
405 fn visit_unit<E>(self) -> Result<Self::Value, E>
406 where
407 E: serde::de::Error, {
408 Ok(Field::Null)
409 }
410 fn visit_none<E>(self) -> Result<Self::Value, E>
411 where
412 E: serde::de::Error, {
413 Ok(Field::Null)
414 }
415
416 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
417 where
418 A: serde::de::SeqAccess<'de>, {
419 let mut vc = Vec::with_capacity(32);
420 while let Some(value) = seq.next_element()? {
421 vc.push(value);
422 }
423 Ok(Field::Array(vc))
424 }
425}