Yams
一个美好的、顺滑的基于 YAML 的解析器,由 LibYAML 构建。
安装
构建 Yams 需要 Xcode 12.5+ 或 Swift 5.4+ 工具链,以及 Swift Package Manager 或 CMake 和 Ninja。
CMake
CMake 3.17.2 或更高版本,以及 Ninja 1.9.0 或更高版本。
在构建非 Apple 平台时
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
为了构建 Apple 平台(macOS、iOS、tvOS、watchOS),不需要单独构建 Foundation,因为它已包含在 SDK 中。
cmake -B /path/to/build -G Ninja -S /path/to/yams -DCMAKE_BUILD_TYPE=Release
cmake --build /path/to/build
Swift Package Manager
将.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.6")
添加到您的Package.swift
文件中的dependencies
。
CocoaPods
在您的Podfile
中添加pod 'Yams'
。
Carthage
将github "jpsim/Yams"
添加到您的Cartfile
。
Bazel
在您的WORKSPACE文件中
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提供了三组转换API:一组用于与Codable
类型一起使用,另一组用于Swift标准库类型,第三组用于Yams原生表示。
可编码
类型
- 可编码是Swift 4中引入的编码和解码策略,它使转换YAML和其他编码器(例如JSONEncoder和PropertyListEncoder)变得简单。
- 最低的计算开销,相当于
Yams.Node
。 - 编码:
YAMLEncoder.encode(_:)
从符合Encodable
协议的实例产生一个YAMLString
。 - 解码:
YAMLDecoder.decode(_:from:)
从YAMLString
或Data
解码符合Decodable
协议的实例。
import Foundation
import Yams
struct S: Codable {
var p: String
}
let s = S(p: "test")
let encoder = YAMLEncoder()
let encodedYAML = try encoder.encode(s)
encodedYAML == """
p: test
"""
let decoder = YAMLDecoder()
let decoded = try decoder.decode(S.self, from: encodedYAML)
s.p == decoded.p
Swift标准库类型
- Swift标准库类型通过匹配正则表达式从内部
Yams.Node
表示形式的 内容推断。 - 当解码YAML时,由于在解码前预先完成所有对象的类型推断,此方法具有最大的计算开销。
- 当处理由
JSONSerialization
创建的对象或输入已经是标准库类型(Any
、Dictionary
、Array
等)时,这种方法可能更容易使用。 - 编码:
Yams.dump(object:)
从Swift标准库类型实例生成一个YAMLString
。 - 解码:
Yams.load(yaml:)
从YAMLString
生成Swift标准库类型实例Any
。
// [String: Any]
let dictionary: [String: Any] = ["key": "value"]
let mapYAML: String = try Yams.dump(object: dictionary)
mapYAML == """
key: value
"""
let loadedDictionary = try Yams.load(yaml: mapYAML) as? [String: Any]
// [Any]
let array: [Int] = [1, 2, 3]
let sequenceYAML: String = try Yams.dump(object: array)
sequenceYAML == """
- 1
- 2
- 3
"""
let loadedArray: [Int]? = try Yams.load(yaml: sequenceYAML) as? [Int]
// Any
let string = "string"
let scalarYAML: String = try Yams.dump(object: string)
scalarYAML == """
string
"""
let loadedString: String? = try Yams.load(yaml: scalarYAML) as? String
Yams.Node
- Yams的本地模型,代表YAML节点,提供所有功能,如检测和自定义YAML格式。
- 根据使用方式,可以最小化计算开销。
- 编码:
Yams.serialize(node:)
从Node
实例生成一个YAMLString
。 - 解码
Yams.compose(yaml:)
从 YAMLString
生成Node
实例。
var map: Yams.Node = [
"array": [
1, 2, 3
]
]
map.mapping?.style = .flow
map["array"]?.sequence?.style = .flow
let yaml = try Yams.serialize(node: map)
yaml == """
{array: [1, 2, 3]}
"""
let node = try Yams.compose(yaml: yaml)
map == node
Combine 集成
与当 Apple 的 Combine 框架可用时,YAMLDecoder
遵循 TopLevelDecoder
协议,这使得它可以使用 decode(type:decoder:)
操作符。
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()
}
许可协议
Yams 和 libYAML 都采用了 MIT 许可。