Skip to main content

nvd_cpe/
part.rs

1//! part
2use crate::error::{CPEError, Result};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::{fmt, str::FromStr};
5
6#[derive(Debug, Clone, PartialEq, Eq, Default)]
7pub enum Part {
8  // any
9  #[default]
10  Any,
11  // 硬件设备 h
12  Hardware,
13  // 操作系统 o
14  OperatingSystem,
15  // 应用程序 a
16  Application,
17}
18
19impl Serialize for Part {
20  fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
21  where
22    S: Serializer,
23  {
24    serializer.serialize_str(match *self {
25      Part::Any => "*",
26      Part::Hardware => "h",
27      Part::Application => "a",
28      Part::OperatingSystem => "o",
29    })
30  }
31}
32
33impl<'de> Deserialize<'de> for Part {
34  fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
35  where
36    D: Deserializer<'de>,
37  {
38    let s = String::deserialize(deserializer)?;
39    Ok(match s.as_str() {
40      "h" => Part::Hardware,
41      "o" => Part::OperatingSystem,
42      "a" => Part::Application,
43      _ => Part::Any,
44    })
45  }
46}
47
48impl From<Part> for char {
49  fn from(val: Part) -> Self {
50    match val {
51      Part::Any => '*',
52      Part::Hardware => 'h',
53      Part::OperatingSystem => 'o',
54      Part::Application => 'a',
55    }
56  }
57}
58impl FromStr for Part {
59  type Err = CPEError;
60
61  fn from_str(val: &str) -> Result<Self> {
62    let c = {
63      let c = val.chars().next();
64      c.ok_or(CPEError::InvalidPart {
65        value: val.to_string(),
66      })?
67    };
68    match c {
69      'h' => Ok(Self::Hardware),
70      'o' => Ok(Self::OperatingSystem),
71      'a' => Ok(Self::Application),
72      _ => Err(CPEError::InvalidPart {
73        value: c.to_string(),
74      }),
75    }
76  }
77}
78
79impl fmt::Display for Part {
80  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81    match self {
82      Self::Hardware => write!(f, "h"),
83      Self::OperatingSystem => write!(f, "o"),
84      Self::Application => write!(f, "a"),
85      Self::Any => {
86        if f.alternate() {
87          write!(f, "*")
88        } else {
89          write!(f, "ANY")
90        }
91      }
92    }
93  }
94}