A sweet and swifty YAML parser built on LibYAML.
Building Yams requires Xcode 12.5+ or a Swift 5.4+ toolchain with the Swift Package Manager or CMake and Ninja.
CMake 3.17.2 or newer is required, along with Ninja 1.9.0 or newer.
When building for non-Apple platforms:
cmake -B /path/to/build -G Ninja -S /path/to/yams -DCMAKE_BUILD_TYPE=Release -DFoundation_DIR=/path/to/foundation/build/cmake/modules
cmake --build /path/to/build
To build for Apple platforms (macOS, iOS, tvOS, watchOS), there is no need to spearately build Foundation because it is included as part of the SDK:
cmake -B /path/to/build -G Ninja -S /path/to/yams -DCMAKE_BUILD_TYPE=Release
cmake --build /path/to/build
Add .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1") to your
Package.swift file's dependencies.
Add pod 'Yams' to your Podfile.
Add github "jpsim/Yams" to your Cartfile.
In your WORKSPACE file
YAMS_GIT_SHA = "SOME_SHA"
http_archive(
name = "com_github_jpsim_yams",
urls = [
"https://github.com/jpsim/Yams/archive/%s.zip" % YAMS_GIT_SHA,
],
strip_prefix = "Yams-%s" % YAMS_GIT_SHA,
)
Yams has three groups of conversion APIs:
one for use with Codable types,
another for Swift Standard Library types,
and a third one for a Yams-native representation.
- Codable is an encoding & decoding strategy introduced in Swift 4 enabling easy conversion between YAML and other Encoders like JSONEncoder and PropertyListEncoder.
- Lowest computational overhead, equivalent to
Yams.Node. - Encoding:
YAMLEncoder.encode(_:)Produces a YAMLStringfrom an instance of type conforming toEncodable. - Decoding:
YAMLDecoder.decode(_:from:)Decodes an instance of type conforming toDecodablefrom YAMLStringorData.
import Foundation
import Yams
structS:Codable{varp:String}lets=S(p:"test")letencoder=YAMLEncoder()letencodedYAML=try encoder.encode(s)
encodedYAML =="""p: test"""letdecoder=YAMLDecoder()letdecoded=try decoder.decode(S.self, from: encodedYAML)
s.p == decoded.p- The type of Swift Standard Library is inferred from the contents of the
internal
Yams.Noderepresentation by matching regular expressions. - This method has the largest computational overhead When decoding YAML, because the type inference of all objects is done up-front.
- It may be easier to use in such a way as to handle objects created from
JSONSerializationor if the input is already standard library types (Any,Dictionary,Array, etc.). - Encoding:
Yams.dump(object:)Produces a YAMLStringfrom an instance of Swift Standard Library types. - Decoding:
Yams.load(yaml:)Produces an instance of Swift Standard Library types asAnyfrom YAMLString.
// [String: Any]
letdictionary:[String:Any]=["key":"value"]letmapYAML:String=tryYams.dump(object: dictionary)
mapYAML =="""key: value"""letloadedDictionary=tryYams.load(yaml: mapYAML)as?[String:Any]
// [Any]
letarray:[Int]=[1,2,3]letsequenceYAML:String=tryYams.dump(object: array)
sequenceYAML =="""- 1- 2- 3"""letloadedArray:[Int]?=tryYams.load(yaml: sequenceYAML)as?[Int]
// Any
letstring="string"letscalarYAML:String=tryYams.dump(object: string)
scalarYAML =="""string"""letloadedString:String?=tryYams.load(yaml: scalarYAML)as?String- Yams' native model representing Nodes of YAML which provides all functions such as detection and customization of the YAML format.
- Depending on how it is used, computational overhead can be minimized.
- Encoding:
Yams.serialize(node:)Produces a YAMLStringfrom an instance ofNode. - Decoding
Yams.compose(yaml:)Produces an instance ofNodefrom YAMLString.
varmap:Yams.Node=["array":[1,2,3]]
map.mapping?.style =.flow
map["array"]?.sequence?.style =.flow
letyaml=tryYams.serialize(node: map)
yaml =="""{array: [1, 2, 3]}"""letnode=tryYams.compose(yaml: yaml)
map == nodeIntegrating with Combine
When Apple's Combine framework is available, YAMLDecoder conforms to the
TopLevelDecoder protocol, which allows it to be used with the
decode(type:decoder:) operator:
import Combine
import Foundation
import Yams
func fetchBook(from url:URL)->AnyPublisher<Book,Error>{URLSession.shared.dataTaskPublisher(for: url).map(\.data).decode(type:Book.self, decoder:YAMLDecoder()).eraseToAnyPublisher()}Both Yams and libYAML are MIT licensed.
