1use std::fmt;
2use std::str::FromStr;
3
4#[derive(Clone, Debug, Eq, Hash, PartialEq)]
23pub struct Target {
24 target: target_lexicon::Triple,
25}
26
27impl Target {
28 pub const fn host() -> Self {
32 Self {
33 target: target_lexicon::HOST,
34 }
35 }
36
37 pub fn try_from_target_triple(triple: &str) -> Result<Self, ParseError> {
43 let platform = target_lexicon::Triple::from_str(triple).map_err(ParseError::from)?;
44
45 Ok(Self { target: platform })
46 }
47
48 pub fn from_target_triple_or_unknown(triple: &str) -> Self {
55 let platform = target_lexicon::Triple::from_str(triple)
56 .unwrap_or_else(|_| target_lexicon::Triple::unknown());
57
58 Self { target: platform }
59 }
60}
61
62impl fmt::Display for Target {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "{}", self.target)
65 }
66}
67
68#[derive(Debug, thiserror::Error)]
70#[non_exhaustive]
71pub enum ParseError {
72 #[error("Unknown architecture `{0}`")]
73 Architecture(String),
74 #[error("Unknown vendor `{0}`")]
75 Vendor(String),
76 #[error("Unknown operating system `{0}`")]
77 OperatingSystem(String),
78 #[error("Unknown environment `{0}`")]
79 Environment(String),
80 #[error("Unknown binary format `{0}`")]
81 BinaryFormat(String),
82 #[error("Unknown field `{0}`")]
83 Field(String),
84}
85
86impl From<target_lexicon::ParseError> for ParseError {
87 fn from(value: target_lexicon::ParseError) -> Self {
88 match value {
89 target_lexicon::ParseError::UnrecognizedArchitecture(v) => ParseError::Architecture(v),
90 target_lexicon::ParseError::UnrecognizedVendor(v) => ParseError::Vendor(v),
91 target_lexicon::ParseError::UnrecognizedOperatingSystem(v) => {
92 ParseError::OperatingSystem(v)
93 }
94 target_lexicon::ParseError::UnrecognizedEnvironment(v) => ParseError::Environment(v),
95 target_lexicon::ParseError::UnrecognizedBinaryFormat(v) => ParseError::BinaryFormat(v),
96 target_lexicon::ParseError::UnrecognizedField(v) => ParseError::Field(v),
97 }
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn create_platform() {
107 let this_platform = Target::host();
108
109 let expected = Target {
110 target: target_lexicon::HOST,
111 };
112
113 assert_eq!(this_platform, expected);
114 }
115
116 #[test]
117 fn to_string() {
118 let target = Target::try_from_target_triple("x86_64-unknown-linux-gnu").unwrap();
119
120 assert_eq!(target.to_string(), "x86_64-unknown-linux-gnu");
121 }
122}