-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reworked YAML file loader mechanics (#26)
- Unified YAML file loader - Better error handling - FileLoader helper
- Loading branch information
Showing
15 changed files
with
313 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// | ||
// File.swift | ||
// toucan | ||
// | ||
// Created by Viasz-Kádi Ferenc on 2024. 10. 10.. | ||
// | ||
|
||
import Foundation | ||
|
||
extension Array { | ||
|
||
/// Appends the given item to the collection if no element in the collection satisfies the specified condition. | ||
/// | ||
/// - Parameters: | ||
/// - item: The element to be appended to the collection if the condition is not met. | ||
/// - condition: A closure that takes an element of the collection as its argument and returns a Boolean value indicating whether the element satisfies the condition. | ||
mutating func appendIfNot( | ||
_ item: Element, | ||
where condition: (Element) -> Bool | ||
) { | ||
if !contains(where: condition) { | ||
append(item) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// | ||
// File.swift | ||
// toucan | ||
// | ||
// Created by Viasz-Kádi Ferenc on 2024. 10. 10.. | ||
// | ||
|
||
import Foundation | ||
|
||
extension String { | ||
|
||
/// Decodes the current instance from a YAML string into a specified type. | ||
/// | ||
/// - Parameter as: The type to decode the YAML string into. | ||
/// - Returns: An optional instance of the specified type, decoded from the YAML string. | ||
/// - Throws: An error if the YAML parsing fails. | ||
func decodeYaml<T>(as: T.Type) throws -> T? { | ||
try YamlParser().parse(self, as: T.self) | ||
} | ||
|
||
/// Decodes a YAML string into a dictionary representation. | ||
/// | ||
/// - Returns: A dictionary with string keys and values of any type, representing the parsed YAML content. | ||
/// Returns `nil` if the parsing fails. | ||
/// - Throws: An error if the YAML parsing fails. | ||
func decodeYaml() throws -> [String: Any]? { | ||
try YamlParser().parse(self) | ||
} | ||
} | ||
|
||
extension [String] { | ||
|
||
/// Decodes an array of YAML-encoded data into a single merged dictionary. | ||
/// | ||
/// - Returns: A dictionary of type `[String: Any]` representing the merged result of decoded YAML data. | ||
/// - Throws: An error if any of the decoding operations fail. | ||
func decodeYaml() throws -> [String: Any] { | ||
try self | ||
.compactMap { | ||
try $0.decodeYaml() | ||
} | ||
.reduce([:]) { partialResult, item in | ||
partialResult.recursivelyMerged(with: item) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// | ||
// File.swift | ||
// toucan | ||
// | ||
// Created by Viasz-Kádi Ferenc on 2024. 10. 10.. | ||
// | ||
|
||
import Foundation | ||
import Yams | ||
|
||
public struct YamlParser { | ||
|
||
/// An enumeration representing possible errors that can occur while parsing the yaml. | ||
public enum Error: Swift.Error { | ||
/// Indicates an error related to parsing YAML. | ||
case yaml(String) | ||
} | ||
|
||
/// A `Resolver` instance used during parsing. | ||
let resolver: Resolver | ||
|
||
/// Initializes a new instance with the specified resolver. | ||
/// - Parameter resolver: The resolver to use for the instance. Defaults to a resolver with the `.timestamp` case removed. | ||
init(resolver: Resolver = .default.removing(.timestamp)) { | ||
self.resolver = resolver | ||
} | ||
|
||
/// Parses a YAML string and attempts to convert it to a specified type. | ||
/// | ||
/// - Parameters: | ||
/// - yaml: The YAML string to parse. | ||
/// - as: The type to which the parsed YAML should be converted. | ||
/// - Returns: An optional value of the specified type if the parsing is successful, or `nil` if the conversion fails. | ||
/// - Throws: An `Error.yaml` if a `YamlError` occurs during parsing. | ||
func parse<T>(_ yaml: String, as: T.Type) throws -> T? { | ||
do { | ||
return try Yams.load(yaml: yaml, resolver) as? T | ||
} | ||
catch let error as YamlError { | ||
throw Error.yaml(error.description) | ||
} | ||
} | ||
|
||
/// Parses a YAML string and converts it into a dictionary. | ||
/// | ||
/// - Parameter yaml: A string containing YAML data. | ||
/// - Returns: A dictionary with string keys and values of any type, or nil if parsing fails. | ||
/// - Throws: An error if the YAML parsing fails. | ||
func parse(_ yaml: String) throws -> [String: Any]? { | ||
try parse(yaml, as: [String: Any].self) | ||
} | ||
|
||
/// Decodes a YAML string into a specified Decodable type. | ||
/// | ||
/// - Parameters: | ||
/// - yaml: A `String` containing the YAML-formatted data to decode. | ||
/// - as: The type of the Decodable object that the YAML data should be decoded into. | ||
/// - Returns: An instance of the specified type, decoded from the provided YAML string. | ||
/// - Throws: An error if the decoding process fails. | ||
func decode<T: Decodable>(_ yaml: String, as type: T.Type) throws -> T { | ||
try YAMLDecoder().decode(T.self, from: yaml) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.