 #endif
 import Foundation
 
+/// Tags describe the the _type_ of a Node.
 public final class Tag {
+    /// Tag name.
     public struct Name: RawRepresentable {
+        /// This `Tag.Name`'s raw string value.
         public let rawValue: String
+        /// Create a `Tag.Name` with a raw string value.
         public init(rawValue: String) {
             self.rawValue = rawValue
         }
     }
 
+    /// Shorthand accessor for `Tag(.implicit)`.
     public static var implicit: Tag {
         return Tag(.implicit)
     }
 
+    /// Create a `Tag` with the specified name, resolver and constructor.
+    ///
+    /// - parameter name:        Tag name.
+    /// - parameter resolver:    `Resolver` this tag should use, `.default` if omitted.
+    /// - parameter constructor: `Constructor` this tag should use, `.default` if omitted.
     public init(_ name: Name,
                 _ resolver: Resolver = .default,
                 _ constructor: Constructor = .default) {

        self.name = name
    }

    public func copy(with name: Name? = nil, resolver: Resolver? = nil, constructor: Constructor? = nil) -> Tag {
        return .init(name ?? self.name, resolver ?? self.resolver, constructor ?? self.constructor)
    }

}

extension Tag: CustomStringConvertible {
    /// A textual representation of this tag.
    public var description: String {
        return name.rawValue
    }
}

extension Tag: Hashable {
    /// :nodoc:
    public var hashValue: Int {
        return name.hashValue
    }

    /// :nodoc:
    public static func == (lhs: Tag, rhs: Tag) -> Bool {
        return lhs.name == rhs.name
    }
}

extension Tag.Name: ExpressibleByStringLiteral {
    /// :nodoc:
    public init(stringLiteral value: String) {
        self.rawValue = value
    }
}

extension Tag.Name: Hashable {
    /// :nodoc:
    public var hashValue: Int {
        return rawValue.hashValue
    }

    /// :nodoc:
    public static func == (lhs: Tag.Name, rhs: Tag.Name) -> Bool {
        return lhs.rawValue == rhs.rawValue
    }
