assemble_rust/
toolchain.rs

1//! Access to rust toolchains
2
3use chrono::{Date, TimeZone, Utc};
4use serde::Serializer;
5use std::fmt::{Display, Formatter};
6
7/// The toolchain channel
8#[derive(Debug, Copy, Clone, Serialize)]
9pub enum Channel {
10    /// The stable channel
11    Stable,
12    /// The beta channel
13    Beta,
14    /// The nightly channel
15    Nightly,
16    /// A specific version of rust
17    Version {
18        /// The major version
19        major: u32,
20        /// The minor version
21        minor: u32,
22        /// An optional patch version. Most recent used if not specified
23        patch: Option<u32>,
24    },
25}
26
27impl Display for Channel {
28    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Channel::Stable => {
31                write!(f, "stable")
32            }
33            Channel::Beta => {
34                write!(f, "beta")
35            }
36            Channel::Nightly => {
37                write!(f, "nightly")
38            }
39            Channel::Version {
40                major,
41                minor,
42                patch,
43            } => match patch {
44                None => {
45                    write!(f, "{}.{}", major, minor)
46                }
47                Some(patch) => {
48                    write!(f, "{}.{}.{}", major, minor, patch)
49                }
50            },
51        }
52    }
53}
54
55/// A rust toolchain
56#[derive(Debug, Serialize, Clone)]
57pub struct Toolchain {
58    /// The channel of the toolchain
59    pub channel: Channel,
60    /// An optional date of the toolchain
61    #[serde(serialize_with = "serialize_date")]
62    pub date: Option<Date<Utc>>,
63    /// An optional target triple for the toolchain
64    pub target_triple: Option<String>,
65}
66
67fn serialize_date<S>(date: &Option<Date<Utc>>, serializer: S) -> Result<S::Ok, S::Error>
68where
69    S: Serializer,
70{
71    match date {
72        None => serializer.serialize_none(),
73        Some(s) => {
74            let date = s.format("%f").to_string();
75            serializer.serialize_some(&date)
76        }
77    }
78}
79
80impl Toolchain {
81    /// Create a new toolchain with a channel
82    pub fn with_channel(channel: Channel) -> Self {
83        Self {
84            channel,
85            date: None,
86            target_triple: None,
87        }
88    }
89
90    /// Create a new toolchain with a specific version
91    pub fn with_version(major: u32, minor: u32) -> Self {
92        Self {
93            channel: Channel::Version {
94                major,
95                minor,
96                patch: None,
97            },
98            date: None,
99            target_triple: None,
100        }
101    }
102
103    /// The stable toolchain
104    pub fn stable() -> Self {
105        Self::with_channel(Channel::Stable)
106    }
107
108    /// The nightly release channel
109    pub fn nightly() -> Self {
110        Self::with_channel(Channel::Nightly)
111    }
112
113    /// A nightly release on a specific date
114    pub fn dated_nightly<Tz: TimeZone>(date: Date<Tz>) -> Self {
115        let mut toolchain = Self::with_channel(Channel::Nightly);
116        toolchain.date = Some(date.with_timezone(&Utc));
117        toolchain
118    }
119}
120
121impl Display for Toolchain {
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        write!(
124            f,
125            "{}{}{}",
126            self.channel,
127            self.date
128                .as_ref()
129                .map(|date| { format!("-{}", date.format("%F")) })
130                .unwrap_or_default(),
131            self.target_triple
132                .as_ref()
133                .map(|s| format!("-{}", s))
134                .unwrap_or_default()
135        )
136    }
137}