1414
1515import RegexBuilder
1616
17- enum ReferenceError : Error { case unexpected( String ) }
18-
1917// https://github.com/distribution/distribution/blob/v2.7.1/reference/reference.go
2018// Split the image reference into a registry and a name part.
2119func splitReference( _ reference: String ) throws -> ( String ? , String ) {
2220 let splits = reference. split ( separator: " / " , maxSplits: 1 , omittingEmptySubsequences: false )
23- if splits. count == 0 { throw ReferenceError . unexpected ( " unexpected error " ) }
21+ if splits. count == 0 { throw ImageReference . ValidationError . unexpected ( " unexpected error " ) }
2422
2523 if splits. count == 1 { return ( nil , reference) }
2624
@@ -39,7 +37,7 @@ func splitName(_ name: String) throws -> (String, String) {
3937 if digestSplit. count == 2 { return ( String ( digestSplit [ 0 ] ) , String ( digestSplit [ 1 ] ) ) }
4038
4139 let tagSplit = name. split ( separator: " : " , maxSplits: 1 , omittingEmptySubsequences: false )
42- if tagSplit. count == 0 { throw ReferenceError . unexpected ( " unexpected error " ) }
40+ if tagSplit. count == 0 { throw ImageReference . ValidationError . unexpected ( " unexpected error " ) }
4341
4442 if tagSplit. count == 1 { return ( name, " latest " ) }
4543
@@ -52,10 +50,14 @@ public struct ImageReference: Sendable, Equatable, CustomStringConvertible, Cust
5250 /// The registry which contains this image
5351 public var registry : String
5452 /// The repository which contains this image
55- public var repository : String
53+ public var repository : Repository
5654 /// The tag identifying the image.
5755 public var reference : String
5856
57+ public enum ValidationError : Error {
58+ case unexpected( String )
59+ }
60+
5961 /// Creates an ImageReference from an image reference string.
6062 /// - Parameters:
6163 /// - reference: The reference to parse.
@@ -72,19 +74,20 @@ public struct ImageReference: Sendable, Equatable, CustomStringConvertible, Cust
7274 // moby/moby assumes that these names refer to images in `library`: `library/swift` or `library/swift:slim`.
7375 // This special case only applies when using Docker Hub, so `example.com/swift` is not expanded `example.com/library/swift`
7476 if self . registry == " index.docker.io " && !repository. contains ( " / " ) {
75- self . repository = " library/ \( repository) "
77+ self . repository = try Repository ( " library/ \( repository) " )
7678 } else {
77- self . repository = repository
79+ self . repository = try Repository ( repository)
7880 }
7981 self . reference = reference
8082 }
8183
8284 /// Creates an ImageReference from separate registry, repository and reference strings.
85+ /// Used only in tests.
8386 /// - Parameters:
8487 /// - registry: The registry which stores the image data.
8588 /// - repository: The repository within the registry which holds the image.
8689 /// - reference: The tag identifying the image.
87- public init ( registry: String , repository: String , reference: String ) {
90+ init ( registry: String , repository: Repository , reference: String ) {
8891 self . registry = registry
8992 self . repository = repository
9093 self . reference = reference
@@ -104,3 +107,33 @@ public struct ImageReference: Sendable, Equatable, CustomStringConvertible, Cust
104107 " ImageReference(registry: \( registry) , repository: \( repository) , reference: \( reference) ) "
105108 }
106109}
110+
111+ extension ImageReference {
112+ /// Repository refers a repository (image namespace) on a container registry
113+ public struct Repository : Sendable , Equatable , CustomStringConvertible , CustomDebugStringConvertible {
114+ var value : String
115+
116+ public enum ValidationError : Error {
117+ case emptyString
118+ }
119+
120+ public init ( _ rawValue: String ) throws {
121+ // Reference handling in github.com/distribution reports empty and uppercase as specific errors.
122+ // All other errors caused are reported as generic format errors.
123+ guard rawValue. count > 0 else {
124+ throw ValidationError . emptyString
125+ }
126+
127+ value = rawValue
128+ }
129+
130+ public var description : String {
131+ value
132+ }
133+
134+ /// Printable description of an ImageReference in a form suitable for debugging.
135+ public var debugDescription : String {
136+ " Repository( \( value) ) "
137+ }
138+ }
139+ }
0 commit comments