1use serde::{Deserialize, Serialize};
2
3use crate::Language;
4
5#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
6pub struct Sdk {
7 name: String,
8 language: Language,
9 #[serde(default, skip_serializing_if = "Option::is_none")]
10 version: Option<String>,
11}
12
13#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
14pub struct SdkModuleReplacement {
15 path: String,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
17 version: Option<String>,
18}
19
20#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
21pub struct SdkModule {
22 path: String,
23 version: String,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 replacement: Option<SdkModuleReplacement>,
26}
27
28#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
29pub struct ResolvedSdk {
30 sdk: Sdk,
31 #[serde(default, skip_serializing_if = "Vec::is_empty")]
32 modules: Vec<SdkModule>,
33}
34
35impl Sdk {
36 #[must_use]
37 pub fn new(name: impl Into<String>, language: Language) -> Self {
38 Self {
39 name: name.into(),
40 language,
41 version: None,
42 }
43 }
44
45 #[must_use]
46 pub fn with_version(mut self, version: impl Into<String>) -> Self {
47 self.version = Some(version.into());
48 self
49 }
50
51 #[must_use]
52 pub fn name(&self) -> &str {
53 &self.name
54 }
55
56 #[must_use]
57 pub const fn language(&self) -> Language {
58 self.language
59 }
60
61 #[must_use]
62 pub fn version(&self) -> Option<&str> {
63 self.version.as_deref()
64 }
65}
66
67impl SdkModuleReplacement {
68 #[must_use]
69 pub fn new(path: impl Into<String>, version: Option<String>) -> Self {
70 Self {
71 path: path.into(),
72 version,
73 }
74 }
75
76 #[must_use]
77 pub fn path(&self) -> &str {
78 &self.path
79 }
80
81 #[must_use]
82 pub fn version(&self) -> Option<&str> {
83 self.version.as_deref()
84 }
85}
86
87impl SdkModule {
88 #[must_use]
89 pub fn new(path: impl Into<String>, version: impl Into<String>) -> Self {
90 Self {
91 path: path.into(),
92 version: version.into(),
93 replacement: None,
94 }
95 }
96
97 #[must_use]
98 pub fn with_replacement(mut self, replacement: SdkModuleReplacement) -> Self {
99 self.replacement = Some(replacement);
100 self
101 }
102
103 #[must_use]
104 pub fn path(&self) -> &str {
105 &self.path
106 }
107
108 #[must_use]
109 pub fn version(&self) -> &str {
110 &self.version
111 }
112
113 #[must_use]
114 pub const fn replacement(&self) -> Option<&SdkModuleReplacement> {
115 self.replacement.as_ref()
116 }
117}
118
119impl ResolvedSdk {
120 #[must_use]
121 pub fn new(sdk: Sdk) -> Self {
122 Self {
123 sdk,
124 modules: Vec::new(),
125 }
126 }
127
128 #[must_use]
129 pub fn with_modules(mut self, modules: impl IntoIterator<Item = SdkModule>) -> Self {
130 self.modules = modules.into_iter().collect();
131 self.modules.sort();
132 self.modules.dedup();
133 self
134 }
135
136 #[must_use]
137 pub const fn sdk(&self) -> &Sdk {
138 &self.sdk
139 }
140
141 #[must_use]
142 pub fn modules(&self) -> &[SdkModule] {
143 &self.modules
144 }
145}