@@ -59,6 +59,16 @@ enum ToolchainSource: Codable, CustomStringConvertible {
5959 }
6060}
6161
62+ private enum ToolchainVersionCodingKeys : String , CodingKey {
63+ case name
64+ case type
65+ case branch
66+ case major
67+ case minor
68+ case patch
69+ case date
70+ }
71+
6272struct AvailableToolchainInfo : OutputData {
6373 let version : ToolchainVersion
6474 let inUse : Bool
@@ -82,24 +92,14 @@ struct AvailableToolchainInfo: OutputData {
8292 private enum CodingKeys : String , CodingKey {
8393 case version
8494 case inUse
85- case `default`
95+ case isDefault
8696 case installed
8797 }
8898
89- private enum ToolchainVersionCodingKeys : String , CodingKey {
90- case name
91- case type
92- case branch
93- case major
94- case minor
95- case patch
96- case date
97- }
98-
9999 public func encode( to encoder: Encoder ) throws {
100100 var container = encoder. container ( keyedBy: CodingKeys . self)
101101 try container. encode ( self . inUse, forKey: . inUse)
102- try container. encode ( self . isDefault, forKey: . default )
102+ try container. encode ( self . isDefault, forKey: . isDefault )
103103 try container. encode ( self . installed, forKey: . installed)
104104
105105 // Encode the version as a object
@@ -131,7 +131,7 @@ struct AvailableToolchainInfo: OutputData {
131131
132132struct AvailableToolchainsListInfo : OutputData {
133133 let toolchains : [ AvailableToolchainInfo ]
134- let selector : ToolchainSelector ?
134+ var selector : ToolchainSelector ?
135135
136136 init ( toolchains: [ AvailableToolchainInfo ] , selector: ToolchainSelector ? = nil ) {
137137 self . toolchains = toolchains
@@ -175,3 +175,163 @@ struct AvailableToolchainsListInfo: OutputData {
175175 return lines. joined ( separator: " \n " )
176176 }
177177}
178+
179+ struct InstallToolchainInfo : OutputData {
180+ let version : ToolchainVersion
181+ let inUse : Bool
182+ let isDefault : Bool
183+
184+ init ( version: ToolchainVersion , inUse: Bool , isDefault: Bool ) {
185+ self . version = version
186+ self . inUse = inUse
187+ self . isDefault = isDefault
188+ }
189+
190+ var description : String {
191+ var message = " \( version) "
192+
193+ if self . inUse {
194+ message += " (in use) "
195+ }
196+ if self . isDefault {
197+ message += " (default) "
198+ }
199+ return message
200+ }
201+
202+ private enum CodingKeys : String , CodingKey {
203+ case version
204+ case inUse
205+ case `default`
206+ }
207+
208+ public func encode( to encoder: Encoder ) throws {
209+ var container = encoder. container ( keyedBy: CodingKeys . self)
210+ try container. encode ( self . inUse, forKey: . inUse)
211+ try container. encode ( self . isDefault, forKey: . default)
212+
213+ // Encode the version as a object
214+ var versionContainer = container. nestedContainer (
215+ keyedBy: ToolchainVersionCodingKeys . self, forKey: . version
216+ )
217+ try versionContainer. encode ( self . version. name, forKey: . name)
218+
219+ switch self . version {
220+ case let . stable( release) :
221+ try versionContainer. encode ( " stable " , forKey: . type)
222+ try versionContainer. encode ( release. major, forKey: . major)
223+ try versionContainer. encode ( release. minor, forKey: . minor)
224+ try versionContainer. encode ( release. patch, forKey: . patch)
225+ case let . snapshot( snapshot) :
226+ try versionContainer. encode ( " snapshot " , forKey: . type)
227+ try versionContainer. encode ( snapshot. date, forKey: . date)
228+ try versionContainer. encode ( snapshot. branch. name, forKey: . branch)
229+
230+ if let major = snapshot. branch. major,
231+ let minor = snapshot. branch. minor
232+ {
233+ try versionContainer. encode ( major, forKey: . major)
234+ try versionContainer. encode ( minor, forKey: . minor)
235+ }
236+ }
237+ }
238+
239+ init ( from decoder: Decoder ) throws {
240+ let container = try decoder. container ( keyedBy: CodingKeys . self)
241+ self . inUse = try container. decode ( Bool . self, forKey: . inUse)
242+ self . isDefault = try container. decode ( Bool . self, forKey: . default)
243+
244+ // Decode the version as a object
245+ let versionContainer = try container. nestedContainer (
246+ keyedBy: ToolchainVersionCodingKeys . self, forKey: . version
247+ )
248+ let name = try versionContainer. decode ( String . self, forKey: . name)
249+
250+ switch try versionContainer. decode ( String . self, forKey: . type) {
251+ case " stable " :
252+ let major = try versionContainer. decode ( Int . self, forKey: . major)
253+ let minor = try versionContainer. decode ( Int . self, forKey: . minor)
254+ let patch = try versionContainer. decode ( Int . self, forKey: . patch)
255+ self . version = . stable(
256+ ToolchainVersion . StableRelease ( major: major, minor: minor, patch: patch) )
257+ case " snapshot " :
258+ let date = try versionContainer. decode ( String . self, forKey: . date)
259+ let branchName = try versionContainer. decode ( String . self, forKey: . branch)
260+ let branchMajor = try ? versionContainer. decodeIfPresent ( Int . self, forKey: . major)
261+ let branchMinor = try ? versionContainer. decodeIfPresent ( Int . self, forKey: . minor)
262+
263+ // Determine the branch from the decoded data
264+ let branch : ToolchainVersion . Snapshot . Branch
265+ if branchName == " main " {
266+ branch = . main
267+ } else if let major = branchMajor, let minor = branchMinor {
268+ branch = . release( major: major, minor: minor)
269+ } else {
270+ branch = . main // Default fallback, adjust based on your needs
271+ }
272+
273+ self . version = . snapshot(
274+ ToolchainVersion . Snapshot (
275+ branch: branch,
276+ date: date
277+ ) )
278+ default :
279+ throw DecodingError . dataCorruptedError (
280+ forKey: ToolchainVersionCodingKeys . type,
281+ in: versionContainer,
282+ debugDescription: " Unknown toolchain type "
283+ )
284+ }
285+ }
286+ }
287+
288+ struct InstalledToolchainsListInfo : OutputData {
289+ let toolchains : [ InstallToolchainInfo ]
290+ var selector : ToolchainSelector ?
291+
292+ private enum CodingKeys : String , CodingKey {
293+ case toolchains
294+ }
295+
296+ var description : String {
297+ var lines : [ String ] = [ ]
298+
299+ if let selector = selector {
300+ let modifier =
301+ switch selector
302+ {
303+ case let . stable( major, minor, nil ) :
304+ if let minor {
305+ " Swift \( major) . \( minor) release "
306+ } else {
307+ " Swift \( major) release "
308+ }
309+ case . snapshot( . main, nil ) :
310+ " main development snapshot "
311+ case let . snapshot( . release( major, minor) , nil ) :
312+ " \( major) . \( minor) development snapshot "
313+ default :
314+ " matching "
315+ }
316+
317+ let header = " Installed \( modifier) toolchains "
318+ lines. append ( header)
319+ lines. append ( String ( repeating: " - " , count: header. count) )
320+ lines. append ( contentsOf: self . toolchains. map ( \. description) )
321+ } else {
322+ let releaseToolchains = self . toolchains. filter { $0. version. isStableRelease ( ) }
323+ let snapshotToolchains = self . toolchains. filter { $0. version. isSnapshot ( ) }
324+
325+ lines. append ( " Installed release toolchains " )
326+ lines. append ( " ---------------------------- " )
327+ lines. append ( contentsOf: releaseToolchains. map ( \. description) )
328+
329+ lines. append ( " " )
330+ lines. append ( " Installed snapshot toolchains " )
331+ lines. append ( " ----------------------------- " )
332+ lines. append ( contentsOf: snapshotToolchains. map ( \. description) )
333+ }
334+
335+ return lines. joined ( separator: " \n " )
336+ }
337+ }
0 commit comments