@@ -401,8 +401,8 @@ extension Arguments: CustomStringConvertible, CustomDebugStringConvertible {
401
401
/// A set of environment variables to use when executing the subprocess.
402
402
public struct Environment : Sendable , Hashable {
403
403
internal enum Configuration : Sendable , Hashable {
404
- case inherit( [ String : String ] )
405
- case custom( [ String : String ] )
404
+ case inherit( [ Key : String ] )
405
+ case custom( [ Key : String ] )
406
406
#if !os(Windows)
407
407
case rawBytes( [ [ UInt8 ] ] )
408
408
#endif
@@ -419,11 +419,11 @@ public struct Environment: Sendable, Hashable {
419
419
return . init( config: . inherit( [ : ] ) )
420
420
}
421
421
/// Override the provided `newValue` in the existing `Environment`
422
- public func updating( _ newValue: [ String : String ] ) -> Self {
422
+ public func updating( _ newValue: [ Key : String ] ) -> Self {
423
423
return . init( config: . inherit( newValue) )
424
424
}
425
425
/// Use custom environment variables
426
- public static func custom( _ newValue: [ String : String ] ) -> Self {
426
+ public static func custom( _ newValue: [ Key : String ] ) -> Self {
427
427
return . init( config: . custom( newValue) )
428
428
}
429
429
@@ -436,6 +436,17 @@ public struct Environment: Sendable, Hashable {
436
436
}
437
437
438
438
extension Environment : CustomStringConvertible , CustomDebugStringConvertible {
439
+ /// A key used to access values in an ``Environment``.
440
+ ///
441
+ /// This type respects the compiled platform's case sensitivity requirements.
442
+ public struct Key {
443
+ public var rawValue : String
444
+
445
+ package init ( _ rawValue: String ) {
446
+ self . rawValue = rawValue
447
+ }
448
+ }
449
+
439
450
/// A textual representation of the environment.
440
451
public var description : String {
441
452
switch self . config {
@@ -464,9 +475,9 @@ extension Environment: CustomStringConvertible, CustomDebugStringConvertible {
464
475
return self . description
465
476
}
466
477
467
- internal static func currentEnvironmentValues( ) -> [ String : String ] {
478
+ internal static func currentEnvironmentValues( ) -> [ Key : String ] {
468
479
return self . withCopiedEnv { environments in
469
- var results : [ String : String ] = [ : ]
480
+ var results : [ Key : String ] = [ : ]
470
481
for env in environments {
471
482
let environmentString = String ( cString: env)
472
483
@@ -488,13 +499,76 @@ extension Environment: CustomStringConvertible, CustomDebugStringConvertible {
488
499
let value = String (
489
500
environmentString [ environmentString. index ( after: delimiter) ..< environmentString. endIndex]
490
501
)
491
- results [ key] = value
502
+ results [ Key ( key) ] = value
492
503
}
493
504
return results
494
505
}
495
506
}
496
507
}
497
508
509
+ extension Environment . Key {
510
+ package static let path : Self = " PATH "
511
+ }
512
+
513
+ extension Environment . Key : CodingKeyRepresentable { }
514
+
515
+ extension Environment . Key : Comparable {
516
+ public static func < ( lhs: Self , rhs: Self ) -> Bool {
517
+ // Even on windows use a stable sort order.
518
+ lhs. rawValue < rhs. rawValue
519
+ }
520
+ }
521
+
522
+ extension Environment . Key : CustomStringConvertible {
523
+ public var description : String { self . rawValue }
524
+ }
525
+
526
+ extension Environment . Key : Encodable {
527
+ public func encode( to encoder: any Swift . Encoder ) throws {
528
+ try self . rawValue. encode ( to: encoder)
529
+ }
530
+ }
531
+
532
+ extension Environment . Key : Equatable {
533
+ public static func == ( _ lhs: Self , _ rhs: Self ) -> Bool {
534
+ #if os(Windows)
535
+ lhs. rawValue. lowercased ( ) == rhs. rawValue. lowercased ( )
536
+ #else
537
+ lhs. rawValue == rhs. rawValue
538
+ #endif
539
+ }
540
+ }
541
+
542
+ extension Environment . Key : ExpressibleByStringLiteral {
543
+ public init ( stringLiteral rawValue: String ) {
544
+ self . init ( rawValue)
545
+ }
546
+ }
547
+
548
+ extension Environment . Key : Decodable {
549
+ public init ( from decoder: any Swift . Decoder ) throws {
550
+ self . rawValue = try String ( from: decoder)
551
+ }
552
+ }
553
+
554
+ extension Environment . Key : Hashable {
555
+ public func hash( into hasher: inout Hasher ) {
556
+ #if os(Windows)
557
+ self . rawValue. lowercased ( ) . hash ( into: & hasher)
558
+ #else
559
+ self . rawValue. hash ( into: & hasher)
560
+ #endif
561
+ }
562
+ }
563
+
564
+ extension Environment . Key : RawRepresentable {
565
+ public init ? ( rawValue: String ) {
566
+ self . rawValue = rawValue
567
+ }
568
+ }
569
+
570
+ extension Environment . Key : Sendable { }
571
+
498
572
// MARK: - TerminationStatus
499
573
500
574
/// An exit status of a subprocess.
0 commit comments