Skip to main content

use_platform/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::{fmt, str::FromStr};
5use std::error::Error;
6
7/// A plain, owned platform triple value.
8#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
9pub struct PlatformTriple(String);
10
11impl PlatformTriple {
12    /// Creates a platform triple from non-empty text.
13    ///
14    /// # Errors
15    ///
16    /// Returns [`PlatformTripleError::Empty`] when the trimmed input is empty.
17    pub fn new(value: impl AsRef<str>) -> Result<Self, PlatformTripleError> {
18        let trimmed = value.as_ref().trim();
19
20        if trimmed.is_empty() {
21            return Err(PlatformTripleError::Empty);
22        }
23
24        Ok(Self(trimmed.to_string()))
25    }
26
27    /// Returns the platform triple text.
28    #[must_use]
29    pub fn as_str(&self) -> &str {
30        &self.0
31    }
32
33    /// Consumes the triple and returns the owned string.
34    #[must_use]
35    pub fn into_string(self) -> String {
36        self.0
37    }
38}
39
40impl AsRef<str> for PlatformTriple {
41    fn as_ref(&self) -> &str {
42        self.as_str()
43    }
44}
45
46impl fmt::Display for PlatformTriple {
47    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
48        formatter.write_str(self.as_str())
49    }
50}
51
52impl FromStr for PlatformTriple {
53    type Err = PlatformTripleError;
54
55    fn from_str(value: &str) -> Result<Self, Self::Err> {
56        Self::new(value)
57    }
58}
59
60/// Errors returned while constructing platform vocabulary.
61#[derive(Clone, Copy, Debug, Eq, PartialEq)]
62pub enum PlatformTripleError {
63    /// The platform triple was empty after trimming whitespace.
64    Empty,
65}
66
67impl fmt::Display for PlatformTripleError {
68    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
69        match self {
70            Self::Empty => formatter.write_str("platform triple cannot be empty"),
71        }
72    }
73}
74
75impl Error for PlatformTripleError {}
76
77/// A plain platform identity value backed by a platform triple.
78#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
79pub struct Platform {
80    triple: PlatformTriple,
81}
82
83impl Platform {
84    /// Creates a platform from an already modeled platform triple.
85    #[must_use]
86    pub const fn new(triple: PlatformTriple) -> Self {
87        Self { triple }
88    }
89
90    /// Returns the platform triple.
91    #[must_use]
92    pub const fn triple(&self) -> &PlatformTriple {
93        &self.triple
94    }
95
96    /// Consumes the platform and returns the platform triple.
97    #[must_use]
98    pub fn into_triple(self) -> PlatformTriple {
99        self.triple
100    }
101}
102
103impl From<PlatformTriple> for Platform {
104    fn from(triple: PlatformTriple) -> Self {
105        Self::new(triple)
106    }
107}
108
109impl fmt::Display for Platform {
110    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
111        self.triple.fmt(formatter)
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use super::{Platform, PlatformTriple, PlatformTripleError};
118
119    #[test]
120    fn accepts_common_platform_triples() {
121        for triple in [
122            "x86_64-unknown-linux-gnu",
123            "aarch64-apple-darwin",
124            "wasm32-wasip1",
125        ] {
126            assert_eq!(PlatformTriple::new(triple).unwrap().as_str(), triple);
127        }
128    }
129
130    #[test]
131    fn rejects_empty_platform_triples() {
132        assert_eq!(PlatformTriple::new("  "), Err(PlatformTripleError::Empty));
133    }
134
135    #[test]
136    fn display_round_trips_through_parse() {
137        let triple = PlatformTriple::new("x86_64-pc-windows-msvc").unwrap();
138        let round_trip: PlatformTriple = triple.to_string().parse().unwrap();
139
140        assert_eq!(round_trip, triple);
141    }
142
143    #[test]
144    fn platform_wraps_a_triple_without_detection() {
145        let triple = PlatformTriple::new("aarch64-apple-darwin").unwrap();
146        let platform = Platform::new(triple.clone());
147
148        assert_eq!(platform.triple(), &triple);
149        assert_eq!(platform.to_string(), "aarch64-apple-darwin");
150    }
151}