@@ -31,7 +31,7 @@ func buildInterpolationResult(_ parts: [VFLInterpolation]) -> (format: String, e
31
31
let format = NSMutableString ( )
32
32
let env = NSMutableArray ( )
33
33
for part in parts {
34
- part. result ( format, env)
34
+ part. resultInto ( format, env)
35
35
if !format. hasSuffix ( " ; " ) {
36
36
format. append ( " ; " )
37
37
}
@@ -59,63 +59,59 @@ public func fullInstall(_ interpolation: [VFLInterpolation]) -> [NSLayoutConstra
59
59
}
60
60
61
61
// MARK: -
62
- public enum VFLInterpolation : ExpressibleByStringInterpolation , ExpressibleByStringLiteral {
62
+ public struct VFLInterpolation : ExpressibleByStringInterpolation , ExpressibleByStringLiteral {
63
+ public struct StringInterpolation : StringInterpolationProtocol {
64
+ public init ( literalCapacity: Int , interpolationCount: Int ) {
65
+ storage. reserveCapacity ( interpolationCount * 2 + 1 )
66
+ }
67
+ public init ( string: String ) {
68
+ storage. append ( . format( string) )
69
+ }
63
70
64
- case format( String )
65
- case metric( CGFloat )
66
- case collection( [ VFLInterpolation ] )
67
- case other( AnyObject )
71
+ public mutating func appendLiteral( _ literal: StringLiteralType ) {
72
+ storage. append ( . format( literal) )
73
+ }
74
+ public mutating func appendInterpolation< T: BinaryFloatingPoint > ( _ value: T ) {
75
+ storage. append ( . metric( CGFloat ( value) ) )
76
+ }
77
+ public mutating func appendInterpolation< T: BinaryInteger > ( _ value: T ) {
78
+ storage. append ( . metric( CGFloat ( value) ) )
79
+ }
80
+ public mutating func appendInterpolation< T: AnyObject > ( _ value: T ) {
81
+ storage. append ( . other( value) )
82
+ }
83
+ public enum Parts {
84
+ /// literal string part
85
+ case format( String )
86
+ /// metrics part
87
+ case metric( CGFloat )
88
+ /// any constraint item type, like View or guide
89
+ case other( AnyObject )
90
+ }
91
+ var storage = [ Parts] ( )
92
+ }
93
+ var parts : StringInterpolation
68
94
69
95
// MARK: ExpressibleByStringLiteral
70
96
public init ( stringLiteral value: StringLiteralType ) {
71
- self = . format ( value)
97
+ parts = StringInterpolation ( string : value)
72
98
}
73
99
74
100
public init ( extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterType ) {
75
- self = . format ( value)
101
+ parts = StringInterpolation ( string : value)
76
102
}
77
103
78
104
public init ( unicodeScalarLiteral value: UnicodeScalarType ) {
79
- self = . format ( value)
105
+ parts = StringInterpolation ( string : value)
80
106
}
81
107
82
108
// MARK: ExpressibleByStringInterpolation
83
- public init ( stringInterpolation strings: VFLInterpolation ... ) {
84
- self = . collection( strings)
85
- }
86
-
87
- public init ( stringInterpolationSegment str: String ) {
88
- self = . format( str)
89
- }
90
-
91
- public init ( stringInterpolationSegment value: CGFloat ) {
92
- self = . metric( value)
109
+ public init ( stringInterpolation: StringInterpolation ) {
110
+ parts = stringInterpolation
93
111
}
94
112
95
- public init < T> ( stringInterpolationSegment expr: T ) {
96
- self = . other( expr as AnyObject )
97
- }
98
-
99
- func result( ) -> ( format: String , env: [ AnyObject ] ) ! {
100
- switch self {
101
- case . collection( let parts) :
102
- let env = NSMutableArray ( capacity: parts. count)
103
- let format = NSMutableString ( )
104
- for part in parts {
105
- part. result ( format, env)
106
- }
107
- return ( format as String , env as [ AnyObject ] )
108
- case . format( let format) :
109
- return ( format, [ ] )
110
- default :
111
- assertionFailure ( " call result on incomplete type " )
112
- return nil
113
- }
114
- }
115
-
116
- /** fill format and env acording to self part */
117
- func result( _ format: NSMutableString , _ env: NSMutableArray ) {
118
- switch self {
113
+ func fillResult( format: NSMutableString , env: NSMutableArray , part: StringInterpolation . Parts ) {
114
+ switch part {
119
115
case . format( let str) :
120
116
format. append ( str)
121
117
case . metric( let value) :
@@ -124,10 +120,21 @@ public enum VFLInterpolation : ExpressibleByStringInterpolation, ExpressibleBySt
124
120
case . other( let obj) :
125
121
format. appendFormat ( " $%u " , env. count)
126
122
env. add ( obj)
127
- case . collection( let parts) : // recursive add format and env
128
- for part in parts {
129
- part. result ( format, env)
130
- }
123
+ }
124
+ }
125
+
126
+ func result( ) -> ( format: String , env: [ AnyObject ] ) ! {
127
+ let parts = self . parts. storage
128
+ let env = NSMutableArray ( capacity: parts. count)
129
+ let format = NSMutableString ( )
130
+ resultInto ( format, env)
131
+ return ( format as String , env as [ AnyObject ] )
132
+ }
133
+
134
+ /// fill format and env acording to self part
135
+ func resultInto( _ format: NSMutableString , _ env: NSMutableArray ) {
136
+ parts. storage. forEach {
137
+ fillResult ( format: format, env: env, part: $0)
131
138
}
132
139
}
133
140
}
0 commit comments