@@ -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,167 @@ 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 isDefault
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: . isDefault)
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: . isDefault)
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+ throw DecodingError . dataCorruptedError (
271+ forKey: ToolchainVersionCodingKeys . branch,
272+ in: versionContainer,
273+ debugDescription: " Invalid branch format: \( branchName) "
274+ )
275+ }
276+
277+ self . version = . snapshot(
278+ ToolchainVersion . Snapshot (
279+ branch: branch,
280+ date: date
281+ ) )
282+ default :
283+ throw DecodingError . dataCorruptedError (
284+ forKey: ToolchainVersionCodingKeys . type,
285+ in: versionContainer,
286+ debugDescription: " Unknown toolchain type "
287+ )
288+ }
289+ }
290+ }
291+
292+ struct InstalledToolchainsListInfo : OutputData {
293+ let toolchains : [ InstallToolchainInfo ]
294+ var selector : ToolchainSelector ?
295+
296+ private enum CodingKeys : String , CodingKey {
297+ case toolchains
298+ }
299+
300+ var description : String {
301+ var lines : [ String ] = [ ]
302+
303+ if let selector = selector {
304+ let modifier =
305+ switch selector
306+ {
307+ case let . stable( major, minor, nil ) :
308+ if let minor {
309+ " Swift \( major) . \( minor) release "
310+ } else {
311+ " Swift \( major) release "
312+ }
313+ case . snapshot( . main, nil ) :
314+ " main development snapshot "
315+ case let . snapshot( . release( major, minor) , nil ) :
316+ " \( major) . \( minor) development snapshot "
317+ default :
318+ " matching "
319+ }
320+
321+ let header = " Installed \( modifier) toolchains "
322+ lines. append ( header)
323+ lines. append ( String ( repeating: " - " , count: header. count) )
324+ lines. append ( contentsOf: self . toolchains. map ( \. description) )
325+ } else {
326+ let releaseToolchains = self . toolchains. filter { $0. version. isStableRelease ( ) }
327+ let snapshotToolchains = self . toolchains. filter { $0. version. isSnapshot ( ) }
328+
329+ lines. append ( " Installed release toolchains " )
330+ lines. append ( " ---------------------------- " )
331+ lines. append ( contentsOf: releaseToolchains. map ( \. description) )
332+
333+ lines. append ( " " )
334+ lines. append ( " Installed snapshot toolchains " )
335+ lines. append ( " ----------------------------- " )
336+ lines. append ( contentsOf: snapshotToolchains. map ( \. description) )
337+ }
338+
339+ return lines. joined ( separator: " \n " )
340+ }
341+ }
0 commit comments