forensic_rs/
artifact.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize,de::Visitor, Deserializer};
3
4use crate::field::Text;
5
6#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
7pub enum Artifact {
8    #[default]
9    Unknown,
10    Other(OtherOS),
11    Windows(WindowsArtifacts),
12    Linux(LinuxArtifacts),
13    MacOs(MacArtifacts),
14    Common(CommonArtifact)
15}
16impl std::fmt::Display for Artifact {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        match self {
19            Artifact::Unknown => write!(f, "Unknown"),
20            Artifact::Other(v) => write!(f, "{}", v),
21            Artifact::Windows(v) => write!(f, "Windows::{}", v),
22            Artifact::Linux(v) => write!(f, "Linux::{}", v),
23            Artifact::MacOs(v) => write!(f, "Mac::{}", v),
24            Artifact::Common(v) => write!(f, "Common::{}", v),
25        }
26    }
27}
28
29#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
30pub struct OtherOS {
31    pub os: Text,
32    pub artifact: Text,
33}
34
35#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
36pub enum WindowsArtifacts {
37    Registry(RegistryArtifacts),
38    MFT,
39    WinEvt(WindowsEvents),
40    Other(String),
41    Prefetch,
42    UAL,
43    Clipboard,
44    ScheduledTasks,
45    GPO,
46    SRU,
47    Startup,
48    RecycleBin,
49    #[default]
50    Unknown,
51}
52#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
53pub enum WindowsEvents {
54    /// Sysmon event
55    Sysmon,
56    /// System event
57    System,
58    /// Security event
59    Security,
60    /// Setup event
61    Setup,
62    /// Application event
63    Application,
64    /// Other events not defined. The value is the Channel of the event.
65    Other(String),
66    #[default]
67    Unknown,
68}
69
70#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
71pub enum RegistryArtifacts {
72    /// Shim Cache
73    ShimCache,
74    /// Shell Bags
75    ShellBags,
76    /// Run and RunOnce keys
77    AutoRuns,
78    Other(String),
79    #[default]
80    Unknown,
81}
82
83#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
84pub enum LinuxArtifacts {
85    Log(String),
86    ShellHistory(String),
87    Cron(String),
88    Service(LinuxService),
89    Other(String),
90    #[default]
91    Unknown,
92}
93
94#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
95pub enum LinuxService {
96    SysV,
97    InitD,
98    SystemD,
99    Other(String),
100    #[default]
101    Unknown,
102}
103
104#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
105pub enum MacArtifacts {
106    Other(String),
107    #[default]
108    Unknown,
109}
110
111#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
112pub enum CommonArtifact {
113    WebBrowsing(WebBrowsingArtifact),
114    Other(String),
115    #[default]
116    Unknown,
117}
118#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
119pub enum WebBrowsingArtifact {
120    BrowserHistory,
121    BrowserStorage,
122    BrowserCache,
123    Cookie,
124    Extension,
125    ExtensionActivity,
126    FileSystem,
127    LocalStorage,
128    Preferences,
129    SessionStorage,
130    Download,
131    AutoFill,
132    RSSFeed,
133    Other(String),
134    #[default]
135    Unknown,
136}
137
138impl Into<Artifact> for WindowsArtifacts {
139    fn into(self) -> Artifact {
140        Artifact::Windows(self)
141    }
142}
143impl Into<Artifact> for RegistryArtifacts {
144    fn into(self) -> Artifact {
145        Artifact::Windows(WindowsArtifacts::Registry(self))
146    }
147}
148impl Into<Artifact> for WindowsEvents {
149    fn into(self) -> Artifact {
150        Artifact::Windows(WindowsArtifacts::WinEvt(self))
151    }
152}
153
154impl Into<WindowsArtifacts> for String {
155    fn into(self) -> WindowsArtifacts {
156        WindowsArtifacts::Other(self)
157    }
158}
159impl Into<RegistryArtifacts> for String {
160    fn into(self) -> RegistryArtifacts {
161        RegistryArtifacts::Other(self)
162    }
163}
164impl Into<WindowsEvents> for String {
165    fn into(self) -> WindowsEvents {
166        WindowsEvents::Other(self)
167    }
168}
169
170impl std::fmt::Display for LinuxArtifacts {
171    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172        match self {
173            LinuxArtifacts::Log(v) => write!(f, "Log::{}", v),
174            LinuxArtifacts::ShellHistory(v) => write!(f, "ShellHistory::{}", v),
175            LinuxArtifacts::Cron(v) => write!(f, "Cron::{}", v),
176            LinuxArtifacts::Service(v) => write!(f, "Service::{}", v),
177            LinuxArtifacts::Other(v) => write!(f, "{}", v),
178            LinuxArtifacts::Unknown => write!(f, "Log::Unknown"),
179        }
180    }
181}
182
183impl std::fmt::Display for LinuxService {
184    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185        match self {
186            LinuxService::InitD => write!(f, "InitD"),
187            LinuxService::SysV => write!(f, "SysV"),
188            LinuxService::SystemD => write!(f, "SystemD"),
189            LinuxService::Unknown => write!(f, "Unknown"),
190            LinuxService::Other(v) => write!(f, "{}", v),
191        }
192    }
193}
194
195impl std::fmt::Display for RegistryArtifacts {
196    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197        match self {
198            RegistryArtifacts::ShimCache => write!(f, "InitD"),
199            RegistryArtifacts::ShellBags => write!(f, "ShellBags"),
200            RegistryArtifacts::AutoRuns => write!(f, "AutoRuns"),
201            RegistryArtifacts::Other(v) => write!(f, "{}", v),
202            RegistryArtifacts::Unknown => write!(f, "Unknown"),
203        }
204    }
205}
206
207impl std::fmt::Display for WindowsEvents {
208    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209        match self {
210            WindowsEvents::Sysmon => write!(f, "Sysmon"),
211            WindowsEvents::System => write!(f, "System"),
212            WindowsEvents::Security => write!(f, "Security"),
213            WindowsEvents::Application => write!(f, "Application"),
214            WindowsEvents::Setup => write!(f, "Setup"),
215            WindowsEvents::Other(v) => write!(f, "{}", v),
216            WindowsEvents::Unknown => write!(f, "Unknown"),
217        }
218    }
219}
220
221impl std::fmt::Display for WindowsArtifacts {
222    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        match self {
224            WindowsArtifacts::Registry(v) => write!(f, "Registry::{}", v),
225            WindowsArtifacts::MFT => write!(f, "MFT"),
226            WindowsArtifacts::WinEvt(v) => write!(f, "WinEvt::{}", v),
227            WindowsArtifacts::Other(v) => write!(f, "{}", v),
228            WindowsArtifacts::Prefetch => write!(f, "Prefetch"),
229            WindowsArtifacts::UAL => write!(f, "UAL"),
230            WindowsArtifacts::Clipboard => write!(f, "Clipboard"),
231            WindowsArtifacts::ScheduledTasks => write!(f, "ScheduledTasks"),
232            WindowsArtifacts::GPO => write!(f, "GPO"),
233            WindowsArtifacts::SRU => write!(f, "SRU"),
234            WindowsArtifacts::Startup => write!(f, "Startup"),
235            WindowsArtifacts::RecycleBin => write!(f, "RecycleBin"),
236            WindowsArtifacts::Unknown => write!(f, "Unknown"),
237        }
238    }
239}
240
241impl std::fmt::Display for MacArtifacts {
242    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243        match self {
244            MacArtifacts::Other(v) => write!(f, "{}", v),
245            MacArtifacts::Unknown => write!(f, "Unknown"),
246        }
247    }
248}
249
250impl std::fmt::Display for OtherOS {
251    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252        write!(f, "{}::{}", self.os, self.artifact)
253    }
254}
255
256impl std::fmt::Display for CommonArtifact {
257    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258        match self {
259            CommonArtifact::WebBrowsing(v) => write!(f, "WebBrowsing::{}", v),
260            CommonArtifact::Other(v) => write!(f, "{}", v),
261            CommonArtifact::Unknown => write!(f, "Unknown"),
262        }
263    }
264}
265impl std::fmt::Display for WebBrowsingArtifact {
266    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
267        match self {
268            WebBrowsingArtifact::AutoFill => write!(f, "AutoFill"),
269            WebBrowsingArtifact::Other(v) => write!(f, "{}", v),
270            WebBrowsingArtifact::Unknown => write!(f, "Unknown"),
271            WebBrowsingArtifact::BrowserHistory  => write!(f, "BrowserHistory"),
272            WebBrowsingArtifact::BrowserStorage  => write!(f, "BrowserStorage"),
273            WebBrowsingArtifact::BrowserCache  => write!(f, "BrowserCache"),
274            WebBrowsingArtifact::Cookie  => write!(f, "Cookie"),
275            WebBrowsingArtifact::Extension  => write!(f, "Extension"),
276            WebBrowsingArtifact::ExtensionActivity  => write!(f, "ExtensionActivity"),
277            WebBrowsingArtifact::FileSystem  => write!(f, "FileSystem"),
278            WebBrowsingArtifact::LocalStorage  => write!(f, "LocalStorage"),
279            WebBrowsingArtifact::Preferences  => write!(f, "Preferences"),
280            WebBrowsingArtifact::SessionStorage  => write!(f, "SessionStorage"),
281            WebBrowsingArtifact::Download  => write!(f, "Download"),
282            WebBrowsingArtifact::RSSFeed  => write!(f, "RSSFeed"),
283        }
284    }
285}
286
287#[cfg(feature = "serde")]
288impl Serialize for Artifact {
289    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
290    where
291        S: serde::Serializer,
292    {
293        serializer.collect_str(&self)
294    }
295}
296#[cfg(feature = "serde")]
297impl Serialize for OtherOS {
298    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
299    where
300        S: serde::Serializer,
301    {
302        serializer.collect_str(&self)
303    }
304}
305#[cfg(feature = "serde")]
306impl Serialize for WindowsArtifacts {
307    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
308    where
309        S: serde::Serializer,
310    {
311        serializer.collect_str(&self)
312    }
313}
314#[cfg(feature = "serde")]
315impl Serialize for WindowsEvents {
316    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
317    where
318        S: serde::Serializer,
319    {
320        serializer.collect_str(&self)
321    }
322}
323#[cfg(feature = "serde")]
324impl Serialize for RegistryArtifacts {
325    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
326    where
327        S: serde::Serializer,
328    {
329        serializer.collect_str(&self)
330    }
331}
332#[cfg(feature = "serde")]
333impl Serialize for LinuxService {
334    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
335    where
336        S: serde::Serializer,
337    {
338        serializer.collect_str(&self)
339    }
340}
341#[cfg(feature = "serde")]
342impl Serialize for MacArtifacts {
343    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
344    where
345        S: serde::Serializer,
346    {
347        serializer.collect_str(&self)
348    }
349}
350#[cfg(feature = "serde")]
351impl<'de> Deserialize<'de> for Artifact {
352    fn deserialize<D>(deserializer: D) -> Result<Artifact, D::Error>
353    where
354        D: Deserializer<'de>,
355    {
356        deserializer.deserialize_str(ArtifactVisitor)
357    }
358}
359#[cfg(feature = "serde")]
360struct LinuxServiceVisitor;
361
362#[cfg(feature = "serde")]
363impl<'de> Visitor<'de> for LinuxServiceVisitor {
364    type Value = LinuxService;
365
366    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
367        formatter.write_str("a linux service name")
368    }
369
370    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
371    where
372        E: serde::de::Error,
373    {
374        Ok(linux_service_from_str(txt))
375    }
376    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
377    where
378        E: serde::de::Error,
379    {
380        self.visit_str(v)
381    }
382    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
383    where
384        E: serde::de::Error,
385    {
386        self.visit_str(&v[..])
387    }
388}
389#[cfg(feature = "serde")]
390pub struct ArtifactVisitor;
391#[cfg(feature = "serde")]
392impl<'de> Visitor<'de> for ArtifactVisitor {
393    type Value = Artifact;
394
395    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
396        formatter.write_str("an artifact name")
397    }
398
399    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
400    where
401        E: serde::de::Error,
402    {
403        Ok(artifact_from_str(v))
404    }
405    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
406    where
407        E: serde::de::Error,
408    {
409        self.visit_str(v)
410    }
411    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
412    where
413        E: serde::de::Error,
414    {
415        self.visit_str(&v[..])
416    }
417}
418
419#[cfg(feature = "serde")]
420struct WindowsArtifactVisitor;
421#[cfg(feature = "serde")]
422impl<'de> Visitor<'de> for WindowsArtifactVisitor {
423    type Value = WindowsArtifacts;
424
425    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
426        formatter.write_str("an artifact name")
427    }
428
429    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
430    where
431        E: serde::de::Error,
432    {
433        Ok(windows_artifacts_from_str(txt))
434    }
435    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
436    where
437        E: serde::de::Error,
438    {
439        self.visit_str(v)
440    }
441    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
442    where
443        E: serde::de::Error,
444    {
445        self.visit_str(&v[..])
446    }
447}
448#[cfg(feature = "serde")]
449struct WinEvtVisitor;
450#[cfg(feature = "serde")]
451impl<'de> Visitor<'de> for WinEvtVisitor {
452    type Value = WindowsEvents;
453
454    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
455        formatter.write_str("a windows event name")
456    }
457
458    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
459    where
460        E: serde::de::Error,
461    {
462        Ok(winevt_artifacts_from_str(txt))
463    }
464    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
465    where
466        E: serde::de::Error,
467    {
468        self.visit_str(v)
469    }
470    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
471    where
472        E: serde::de::Error,
473    {
474        self.visit_str(&v[..])
475    }
476}
477#[cfg(feature = "serde")]
478struct RegistryArtifactsVisitor;
479#[cfg(feature = "serde")]
480impl<'de> Visitor<'de> for RegistryArtifactsVisitor {
481    type Value = RegistryArtifacts;
482
483    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
484        formatter.write_str("a registry name")
485    }
486
487    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
488    where
489        E: serde::de::Error,
490    {
491        Ok(registry_artifacts_from_str(txt))
492    }
493    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
494    where
495        E: serde::de::Error,
496    {
497        self.visit_str(v)
498    }
499    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
500    where
501        E: serde::de::Error,
502    {
503        self.visit_str(&v[..])
504    }
505}
506#[cfg(feature = "serde")]
507struct OtherOsVisitor;
508#[cfg(feature = "serde")]
509impl<'de> Visitor<'de> for OtherOsVisitor {
510    type Value = OtherOS;
511
512    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
513        formatter.write_str("a Operating System name")
514    }
515
516    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
517    where
518        E: serde::de::Error,
519    {
520        Ok(other_artifact_from_str(txt))
521    }
522    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
523    where
524        E: serde::de::Error,
525    {
526        self.visit_str(v)
527    }
528    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
529    where
530        E: serde::de::Error,
531    {
532        self.visit_str(&v[..])
533    }
534}
535
536#[cfg(feature = "serde")]
537struct LinuxArtifactVisitor;
538#[cfg(feature = "serde")]
539impl<'de> Visitor<'de> for LinuxArtifactVisitor {
540    type Value = LinuxArtifacts;
541
542    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
543        formatter.write_str("a Operating System name")
544    }
545
546    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
547    where
548        E: serde::de::Error,
549    {
550        Ok(linux_artifacts_from_str(txt))
551    }
552    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
553    where
554        E: serde::de::Error,
555    {
556        self.visit_str(v)
557    }
558    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
559    where
560        E: serde::de::Error,
561    {
562        self.visit_str(&v[..])
563    }
564}
565#[cfg(feature = "serde")]
566struct MacOsArtifactVisitor;
567#[cfg(feature = "serde")]
568impl<'de> Visitor<'de> for MacOsArtifactVisitor {
569    type Value = MacArtifacts;
570
571    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
572        formatter.write_str("Invalid Mac artifact")
573    }
574
575    fn visit_str<E>(self, txt: &str) -> Result<Self::Value, E>
576    where
577        E: serde::de::Error,
578    {
579        let (artifact, subartifact) = match txt.find("::") {
580            Some(v) => (&txt[0..v], &txt[v+2..]),
581            None => (txt, "")
582        };
583        Ok(match artifact {
584            "Unknown" => Self::Value::Unknown,
585            _ => Self::Value::Other(subartifact.to_string()),
586        })
587    }
588    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
589    where
590        E: serde::de::Error,
591    {
592        self.visit_str(v)
593    }
594    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
595    where
596        E: serde::de::Error,
597    {
598        self.visit_str(&v[..])
599    }
600}
601
602pub fn artifact_from_str(txt : &str) -> Artifact {
603    let (os, artifact) = match txt.split_once("::") {
604        Some(v) => v,
605        None => return Artifact::Unknown,
606    };
607    match os {
608        "Unknown" => Artifact::Unknown,
609        "Windows" => Artifact::Windows(windows_artifacts_from_str(artifact)),
610        "Linux" => Artifact::Linux(linux_artifacts_from_str(artifact)),
611        "MacOs" => Artifact::MacOs(mac_artifact_from_str(artifact)),
612        "Common" => Artifact::Common(common_artifact_from_str(artifact)),
613        _ => Artifact::Other(other_artifact_from_str(txt)),
614    }
615}
616pub fn windows_artifacts_from_str(txt : &str) -> WindowsArtifacts {
617    let (artifact, subartifact) = match txt.find("::") {
618        Some(v) => (&txt[0..v], &txt[v+2..]),
619        None => (&txt[..], ""),
620    };
621    match artifact {
622        "Unknown" => WindowsArtifacts::Unknown,
623        "Registry" => WindowsArtifacts::Registry(registry_artifacts_from_str(subartifact)),
624        "MFT" => WindowsArtifacts::MFT,
625        "Prefetch" => WindowsArtifacts::Prefetch,
626        "WinEvt" => WindowsArtifacts::WinEvt(winevt_artifacts_from_str(subartifact)),
627        "UAL" => WindowsArtifacts::UAL,
628        "Clipboard" => WindowsArtifacts::Clipboard,
629        "ScheduledTasks" => WindowsArtifacts::ScheduledTasks,
630        "GPO" => WindowsArtifacts::GPO,
631        "SRU" => WindowsArtifacts::SRU,
632        "Startup" => WindowsArtifacts::Startup,
633        "RecycleBin" => WindowsArtifacts::RecycleBin,
634        _ => WindowsArtifacts::Other(subartifact.to_string())
635    }
636}
637
638pub fn registry_artifacts_from_str(txt : &str) -> RegistryArtifacts {
639    match txt {
640        "Unknown" => RegistryArtifacts::Unknown,
641        "ShimCache" => RegistryArtifacts::ShimCache,
642        "ShellBags" => RegistryArtifacts::ShellBags,
643        "AutoRuns" => RegistryArtifacts::AutoRuns,
644        _ => RegistryArtifacts::Other(txt.to_string())
645    }
646}
647
648pub fn winevt_artifacts_from_str(txt : &str) -> WindowsEvents {
649    match txt {
650        "Unknown" => WindowsEvents::Unknown,
651        "Sysmon" => WindowsEvents::Sysmon,
652        "System" => WindowsEvents::System,
653        "Security" => WindowsEvents::Security,
654        _ => WindowsEvents::Other(txt.to_string())
655    }
656}
657
658pub fn linux_artifacts_from_str(txt : &str) -> LinuxArtifacts {
659    let (artifact, subartifact) = match txt.find("::") {
660        Some(v) => (&txt[0..v], &txt[v+2..]),
661        None => return LinuxArtifacts::Unknown
662    };
663    match artifact {
664        "Log" => LinuxArtifacts::Log(subartifact.to_string()),
665        "ShellHistory" => LinuxArtifacts::ShellHistory(subartifact.to_string()),
666        "Cron" => LinuxArtifacts::Cron(subartifact.to_string()),
667        "Service" => LinuxArtifacts::Service(linux_service_from_str(txt)),
668        _ => LinuxArtifacts::Other(subartifact.to_string()),
669    }
670}
671pub fn linux_service_from_str(txt : &str) -> LinuxService {
672    match txt {
673        "SysV" => LinuxService::SysV,
674        "InitD" => LinuxService::InitD,
675        "SystemD" => LinuxService::SystemD,
676        "Unknown" => LinuxService::Unknown,
677        _ => LinuxService::Other(txt.to_string())
678    }
679}
680
681pub fn mac_artifact_from_str(txt : &str) -> MacArtifacts {
682    match txt {
683        "Unknown" => MacArtifacts::Unknown,
684        _ => MacArtifacts::Other(txt.to_string())
685    }
686}
687pub fn common_artifact_from_str(txt : &str) -> CommonArtifact {
688    let (artifact, subartifact) = match txt.find("::") {
689        Some(v) => (&txt[0..v], &txt[v+2..]),
690        None => return CommonArtifact::Unknown
691    };
692    match artifact {
693        "Unknown" => CommonArtifact::Unknown,
694        "WebBrowsing" => CommonArtifact::WebBrowsing(webbrowsing_artifact_from_str(subartifact)),
695        _ => CommonArtifact::Other(txt.to_string())
696    }
697}
698pub fn webbrowsing_artifact_from_str(txt : &str) -> WebBrowsingArtifact {
699    match txt {
700        "AutoFill" => WebBrowsingArtifact::AutoFill,
701        "BrowserCache" => WebBrowsingArtifact::BrowserCache,
702        "BrowserHistory" => WebBrowsingArtifact::BrowserHistory,
703        "BrowserStorage" => WebBrowsingArtifact::BrowserStorage,
704        "Cookie" => WebBrowsingArtifact::Cookie,
705        "Download" => WebBrowsingArtifact::Download,
706        "Extension" => WebBrowsingArtifact::Extension,
707        "ExtensionActivity" => WebBrowsingArtifact::ExtensionActivity,
708        "FileSystem" => WebBrowsingArtifact::FileSystem,
709        "LocalStorage" => WebBrowsingArtifact::LocalStorage,
710        "Preferences" => WebBrowsingArtifact::Preferences,
711        "RSSFeed" => WebBrowsingArtifact::RSSFeed,
712        "SessionStorage" => WebBrowsingArtifact::SessionStorage,
713        "Unknown" => WebBrowsingArtifact::Unknown,
714        _ => WebBrowsingArtifact::Other(txt.to_string())
715    }
716}
717pub fn other_artifact_from_str(txt : &str) -> OtherOS {
718    let (os, subartifact) = match txt.find("::") {
719        Some(v) => (&txt[0..v], &txt[v+2..]),
720        None =>  return OtherOS { os: std::borrow::Cow::Owned("Unknown".to_string()), artifact: std::borrow::Cow::Owned("Unknown".to_string()) }
721    };
722    OtherOS { os: std::borrow::Cow::Owned(os.to_string()), artifact: std::borrow::Cow::Owned(subartifact.to_string()) }
723}
724
725impl From<&str> for Artifact {
726    fn from(txt: &str) -> Self {
727        artifact_from_str(txt)
728    }
729}
730impl From<&String> for Artifact {
731    fn from(txt: &String) -> Self {
732        artifact_from_str(txt)
733    }
734}
735impl From<String> for Artifact {
736    fn from(txt: String) -> Self {
737        artifact_from_str(&txt)
738    }
739}