Add docstrings to Node.swift

This commit is contained in:
JP Simard 2018-04-29 16:37:33 -07:00
parent cdea3d3d4b
commit 05fc492d44
No known key found for this signature in database
GPG Key ID: 184C3F2916202C58
1 changed files with 69 additions and 5 deletions

View File

@ -8,28 +8,51 @@
import Foundation
/// YAML Node.
public enum Node {
/// Scalar node.
case scalar(Scalar)
/// Mapping node.
case mapping(Mapping)
/// Sequence node.
case sequence(Sequence)
}
extension Node {
/// Create a `Node.scalar` with a string, tag & scalar style.
///
/// - parameter string: String value for this node.
/// - parameter tag: Tag for this node.
/// - parameter style: Style to use when emitting this node.
public init(_ string: String, _ tag: Tag = .implicit, _ style: Scalar.Style = .any) {
self = .scalar(.init(string, tag, style))
}
/// Create a `Node.mapping` with a sequence of node pairs, tag & scalar style.
///
/// - parameter pairs: Pairs of nodes to use for this node.
/// - parameter tag: Tag for this node.
/// - parameter style: Style to use when emitting this node.
public init(_ pairs: [(Node, Node)], _ tag: Tag = .implicit, _ style: Mapping.Style = .any) {
self = .mapping(.init(pairs, tag, style))
}
/// Create a `Node.sequence` with a sequence of nodes, tag & scalar style.
///
/// - parameter nodes: Sequence of nodes to use for this node.
/// - parameter tag: Tag for this node.
/// - parameter style: Style to use when emitting this node.
public init(_ nodes: [Node], _ tag: Tag = .implicit, _ style: Sequence.Style = .any) {
self = .sequence(.init(nodes, tag, style))
}
}
// MARK: - Public Node Members
extension Node {
/// Accessing this property causes the tag to be resolved by tag.resolver.
/// The tag for this node.
///
/// - note: Accessing this property causes the tag to be resolved by tag.resolver.
public var tag: Tag {
switch self {
case let .scalar(scalar): return scalar.resolvedTag
@ -38,6 +61,7 @@ extension Node {
}
}
/// The location for this node.
public var mark: Mark? {
switch self {
case let .scalar(scalar): return scalar.mark
@ -46,54 +70,67 @@ extension Node {
}
}
// MARK: typed accessor properties
// MARK: - Typed accessor properties
/// This node as an `Any`, if convertible.
public var any: Any {
return tag.constructor.any(from: self)
}
/// This node as a `String`, if convertible.
public var string: String? {
return String.construct(from: self)
}
/// This node as a `Bool`, if convertible.
public var bool: Bool? {
return scalar.flatMap(Bool.construct)
}
/// This node as a `Double`, if convertible.
public var float: Double? {
return scalar.flatMap(Double.construct)
}
/// This node as an `NSNull`, if convertible.
public var null: NSNull? {
return scalar.flatMap(NSNull.construct)
}
/// This node as an `Int`, if convertible.
public var int: Int? {
return scalar.flatMap(Int.construct)
}
/// This node as a `Data`, if convertible.
public var binary: Data? {
return scalar.flatMap(Data.construct)
}
/// This node as a `Date`, if convertible.
public var timestamp: Date? {
return scalar.flatMap(Date.construct)
}
// MARK: Typed accessor methods
/// - Returns: Array of `Node`
/// Returns this node mapped as an `Array<Node>`. If the node isn't a `Node.sequence`, the array will be
/// empty.
public func array() -> [Node] {
return sequence.map(Array.init) ?? []
}
/// Typed Array using type parameter: e.g. `array(of: String.self)`
///
/// - Parameter type: Type conforms to ScalarConstructible
/// - Returns: Array of `Type`
/// - parameter type: Type conforming to `ScalarConstructible`.
///
/// - returns: Array of `Type`.
public func array<Type: ScalarConstructible>(of type: Type.Type = Type.self) -> [Type] {
return sequence?.compactMap { $0.scalar.flatMap(type.construct) } ?? []
}
/// If the node is a `.sequence` or `.mapping`, set or get the specified node.
/// If the node is a `.scalar`, this is a no-op.
public subscript(node: Node) -> Node? {
get {
switch self {
@ -120,6 +157,9 @@ extension Node {
}
}
/// If the node is a `.sequence` or `.mapping`, set or get the specified parameter's `Node`
/// representation.
/// If the node is a `.scalar`, this is a no-op.
public subscript(representable: NodeRepresentable) -> Node? {
get {
guard let node = try? representable.represented() else { return nil }
@ -131,6 +171,8 @@ extension Node {
}
}
/// If the node is a `.sequence` or `.mapping`, set or get the specified string's `Node` representation.
/// If the node is a `.scalar`, this is a no-op.
public subscript(string: String) -> Node? {
get {
return self[Node(string, tag.copy(with: .implicit))]
@ -142,7 +184,9 @@ extension Node {
}
// MARK: Hashable
extension Node: Hashable {
/// This `Node`'s Hashable `hashValue`.
public var hashValue: Int {
switch self {
case let .scalar(scalar):
@ -154,6 +198,12 @@ extension Node: Hashable {
}
}
/// Returns true if both nodes are equal.
///
/// - parameter lhs: The left hand side Node to compare.
/// - parameter rhs: The right hand side Node to compare.
///
/// - returns: True if both nodes are equal.
public static func == (lhs: Node, rhs: Node) -> Bool {
switch (lhs, rhs) {
case let (.scalar(lhs), .scalar(rhs)):
@ -168,7 +218,15 @@ extension Node: Hashable {
}
}
// MARK: Comparable
extension Node: Comparable {
/// Returns true if `lhs` is ordered before `rhs`.
///
/// - parameter lhs: The left hand side Node to compare.
/// - parameter rhs: The right hand side Node to compare.
///
/// - returns: True if `lhs` is ordered before `rhs`.
public static func < (lhs: Node, rhs: Node) -> Bool {
switch (lhs, rhs) {
case let (.scalar(lhs), .scalar(rhs)):
@ -197,31 +255,37 @@ extension Array where Element: Comparable {
}
// MARK: - ExpressibleBy*Literal
extension Node: ExpressibleByArrayLiteral {
/// Create a `Node.sequence` from an array literal of `Node`s.
public init(arrayLiteral elements: Node...) {
self = .sequence(.init(elements))
}
}
extension Node: ExpressibleByDictionaryLiteral {
/// Create a `Node.mapping` from a dictionary literal of `Node`s.
public init(dictionaryLiteral elements: (Node, Node)...) {
self = Node(elements)
}
}
extension Node: ExpressibleByFloatLiteral {
/// Create a `Node.scalar` from a float literal.
public init(floatLiteral value: Double) {
self.init(String(value), Tag(.float))
}
}
extension Node: ExpressibleByIntegerLiteral {
/// Create a `Node.scalar` from an integer literal.
public init(integerLiteral value: Int) {
self.init(String(value), Tag(.int))
}
}
extension Node: ExpressibleByStringLiteral {
/// Create a `Node.scalar` from a string literal.
public init(stringLiteral value: String) {
self.init(value)
}