rust_toolchain/
toolchain.rs

1use crate::{Channel, Component, Date, Target};
2use std::collections::HashSet;
3
4/// A Rust toolchain
5///
6/// # Reading materials
7///
8/// - [`rustup concepts: toolchains`]
9///
10/// [`rustup concepts: toolchains`]: https://rust-lang.github.io/rustup/concepts/toolchains.html
11#[derive(Clone, Debug, PartialEq, Eq)]
12#[non_exhaustive]
13pub struct Toolchain {
14    channel: Channel,
15    date: Option<Date>,
16    host: Target,
17
18    components: HashSet<Component>,
19    targets: HashSet<Target>,
20}
21
22impl Toolchain {
23    /// Create a new toolchain instance
24    pub fn new(
25        channel: Channel,
26        date: Option<Date>,
27        host: Target,
28        components: HashSet<Component>,
29        targets: HashSet<Target>,
30    ) -> Self {
31        Self {
32            channel,
33            date,
34            host,
35            components,
36            targets,
37        }
38    }
39
40    /// The release associated with the toolchain
41    pub fn channel(&self) -> &Channel {
42        &self.channel
43    }
44
45    /// The date on which the toolchain was released
46    pub fn date(&self) -> Option<&Date> {
47        self.date.as_ref()
48    }
49
50    /// The host target associated with the toolchain
51    pub fn host(&self) -> &Target {
52        &self.host
53    }
54
55    /// The components associated with the toolchain
56    pub fn components(&self) -> &HashSet<Component> {
57        &self.components
58    }
59
60    /// The targets associated with the toolchain
61    pub fn targets(&self) -> &HashSet<Target> {
62        &self.targets
63    }
64
65    /// Update the associated channel
66    pub fn set_channel(&mut self, channel: Channel) {
67        self.channel = channel;
68    }
69
70    /// Update the associated toolchain release date
71    pub fn set_date(&mut self, date: Option<Date>) {
72        self.date = date;
73    }
74
75    /// Updated the associated host platform
76    pub fn set_host(&mut self, host: Target) {
77        self.host = host;
78    }
79
80    /// Update the associated toolchain components
81    pub fn set_components(&mut self, components: HashSet<Component>) {
82        self.components = components;
83    }
84
85    /// Update the associated toolchain targets
86    pub fn set_targets(&mut self, targets: HashSet<Target>) {
87        self.targets = targets;
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use crate::RustVersion;
95
96    #[test]
97    fn create_toolchain() {
98        let channel = Channel::stable(RustVersion::new(1, 2, 3));
99
100        let toolchain = Toolchain::new(
101            channel,
102            None,
103            Target::host(),
104            HashSet::new(),
105            HashSet::new(),
106        );
107
108        assert!(toolchain.channel().is_stable());
109        assert_eq!(toolchain.host(), &Target::host());
110    }
111
112    #[test]
113    fn channel() {
114        let channel = Channel::stable(RustVersion::new(1, 2, 3));
115        let mut toolchain = Toolchain::new(
116            channel,
117            None,
118            Target::host(),
119            HashSet::new(),
120            HashSet::new(),
121        );
122
123        assert!(toolchain.channel().is_stable());
124
125        toolchain.set_channel(Channel::beta(RustVersion::new(1, 2, 4)));
126
127        assert!(toolchain.channel().is_beta());
128    }
129
130    #[test]
131    fn date() {
132        let channel = Channel::stable(RustVersion::new(1, 2, 3));
133        let mut toolchain = Toolchain::new(
134            channel,
135            None,
136            Target::host(),
137            HashSet::new(),
138            HashSet::new(),
139        );
140
141        assert!(toolchain.date().is_none());
142
143        toolchain.set_date(Some(Date::new(2025, 1, 2)));
144
145        assert_eq!(toolchain.date().unwrap().year(), 2025);
146        assert_eq!(toolchain.date().unwrap().month(), 1);
147        assert_eq!(toolchain.date().unwrap().day(), 2);
148    }
149
150    #[test]
151    fn host() {
152        let channel = Channel::stable(RustVersion::new(1, 2, 3));
153        let mut toolchain = Toolchain::new(
154            channel,
155            None,
156            Target::host(),
157            HashSet::new(),
158            HashSet::new(),
159        );
160
161        assert_eq!(toolchain.host(), &Target::host());
162
163        toolchain.set_host(Target::from_target_triple_or_unknown("make it unknown"));
164
165        assert_eq!(
166            toolchain.host(),
167            &Target::from_target_triple_or_unknown("make it unknown")
168        );
169    }
170
171    #[test]
172    fn components() {
173        let channel = Channel::stable(RustVersion::new(1, 2, 3));
174        let mut toolchain = Toolchain::new(
175            channel,
176            None,
177            Target::host(),
178            HashSet::new(),
179            HashSet::new(),
180        );
181
182        assert!(toolchain.components().is_empty());
183
184        let mut set = HashSet::new();
185        set.insert(Component::new("hello"));
186        set.insert(Component::new("world"));
187
188        let expected = set.clone();
189
190        toolchain.set_components(set);
191
192        assert_eq!(toolchain.components(), &expected);
193    }
194
195    #[test]
196    fn targets() {
197        let channel = Channel::stable(RustVersion::new(1, 2, 3));
198        let mut toolchain = Toolchain::new(
199            channel,
200            None,
201            Target::host(),
202            HashSet::new(),
203            HashSet::new(),
204        );
205
206        assert!(toolchain.targets().is_empty());
207
208        let mut set = HashSet::new();
209        set.insert(Target::from_target_triple_or_unknown("hello"));
210
211        let expected = set.clone();
212
213        toolchain.set_targets(set);
214
215        assert_eq!(toolchain.targets(), &expected);
216    }
217}