diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/grain.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/grain.xcscheme
index ea116bd..9291ddc 100644
--- a/.swiftpm/xcode/xcshareddata/xcschemes/grain.xcscheme
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/grain.xcscheme
@@ -93,6 +93,10 @@
+
+
diff --git a/Package.resolved b/Package.resolved
index cdf10b9..ef8f64a 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -35,6 +35,15 @@
"revision" : "0b77e67c484e532444ceeab60119b8536f8cd648",
"version" : "0.3.0"
}
+ },
+ {
+ "identity" : "yams",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/jpsim/Yams.git",
+ "state" : {
+ "revision" : "01835dc202670b5bb90d07f3eae41867e9ed29f6",
+ "version" : "5.0.1"
+ }
}
],
"version" : 2
diff --git a/Package.swift b/Package.swift
index 1066ce8..ca416b8 100644
--- a/Package.swift
+++ b/Package.swift
@@ -19,12 +19,14 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.1.0"),
.package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.2.7"),
- .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.6.2")
+ .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.6.2"),
+ .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1")
],
targets: [
.target(
name: "GrainDescriptor",
dependencies: [
+ "Yams",
"Alamofire",
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
],
diff --git a/Sources/Fixture.swift b/Sources/Fixture.swift
index 3055891..207a259 100644
--- a/Sources/Fixture.swift
+++ b/Sources/Fixture.swift
@@ -2,9 +2,9 @@ import GrainDescriptor
import Foundation
import Alamofire
-let response = try await AF.request("https://httpbin.org/get").serializingString().value
+//let response = try await AF.request("https://httpbin.org/get").serializingString().value
-serialize {
+serialize(.yaml) {
GrainObject {
GrainMember("data") {
@@ -13,9 +13,9 @@ serialize {
.init(name: "B", age: 2),
])
}
- GrainMember("result") {
- response
- }
+// GrainMember("result") {
+// response
+// }
GrainMember("context") {
context.filePath.pathString
}
diff --git a/Sources/Grain/CLI.swift b/Sources/Grain/CLI.swift
index ce9777c..2fa464d 100644
--- a/Sources/Grain/CLI.swift
+++ b/Sources/Grain/CLI.swift
@@ -42,8 +42,9 @@ struct CLI: AsyncParsableCommand {
}
- @Argument var targetFilePaths: [String]
+ @Argument(completion: .directory) var targetFilePaths: [String]
@Option(name: .customLong("output")) var outputDirectory: String?
+ @Option(help: "a parameter to inject json as Context") var userInfo: String?
@Flag var verbose = false
func run() async throws {
@@ -59,7 +60,8 @@ struct CLI: AsyncParsableCommand {
let context = GrainDescriptor.Context(
filePath: path,
- outputDir: outputDirectory.map { AbsolutePath($0, relativeTo: localFileSystem.currentWorkingDirectory!) }
+ outputDir: outputDirectory.map { AbsolutePath($0, relativeTo: localFileSystem.currentWorkingDirectory!) },
+ userInfoString: userInfo
)
try await self.render(path, context: context)
diff --git a/Sources/GrainDescriptor/Entrypoint.swift b/Sources/GrainDescriptor/Entrypoint.swift
index 07facbc..6fa4f78 100644
--- a/Sources/GrainDescriptor/Entrypoint.swift
+++ b/Sources/GrainDescriptor/Entrypoint.swift
@@ -2,7 +2,11 @@ import Alamofire
@_implementationOnly import Darwin.C
import Foundation
import TSCBasic
+import Yams
+/**
+ The strategy to use serialization as `Data`
+ */
public struct Serialization {
private let _encode: (any GrainView) throws -> Data
@@ -43,6 +47,45 @@ public struct Serialization {
)
}
+
+ public static var plist: Self {
+ plist(outputFormat: .xml)
+ }
+
+ public static func plist(
+ outputFormat: PropertyListSerialization.PropertyListFormat
+ ) -> Self {
+
+ let encoder = PropertyListEncoder()
+
+ return .init(
+ fileExtension: "plist",
+ encode: {
+ try encoder.encode($0)
+ }
+ )
+
+ }
+
+ public static var yaml: Self {
+ yaml(options: .init())
+ }
+
+ public static func yaml(options: YAMLEncoder.Options) -> Self {
+
+ let encoder = YAMLEncoder()
+
+ encoder.options = options
+
+ return .init(
+ fileExtension: "yml",
+ encode: {
+ let string = try encoder.encode($0)
+ return string.data(using: .utf8)!
+ }
+ )
+
+ }
public func encode(_ view: some GrainView) throws -> Data {
return try _encode(view)
@@ -51,16 +94,23 @@ public struct Serialization {
}
public struct Context: Codable {
+
+ public enum DomainError: Int, Error {
+ case contextNotProvided
+ }
public let filePath: AbsolutePath
public let outputDir: AbsolutePath?
+ public let userInfoString: String?
public init(
filePath: AbsolutePath,
- outputDir: AbsolutePath?
+ outputDir: AbsolutePath?,
+ userInfoString: String?
) {
self.filePath = filePath
self.outputDir = outputDir
+ self.userInfoString = userInfoString
}
public func json() -> String {
@@ -79,6 +129,15 @@ public struct Context: Codable {
let url = URL(fileURLWithPath: path.pathString)
try data.write(to: url, options: [.atomic])
}
+
+ public func userInfo(_ decodableType: T.Type) throws -> T {
+ guard let userInfoString else {
+ throw DomainError.contextNotProvided
+ }
+ let decoder = JSONDecoder()
+ let decoded = try decoder.decode(decodableType.self, from: userInfoString.data(using: .utf8)!)
+ return decoded
+ }
}
@@ -144,6 +203,14 @@ public struct Output {
}
+public func serialize(
+ _ serialization: Serialization = .json,
+ output: Output = .stdout,
+ @GrainBuilder _ thunk: () throws -> some GrainView
+) {
+ serialize(serialization: serialization, output: output, thunk)
+}
+
public func serialize(
serialization: Serialization = .json,
output: Output = .stdout,
diff --git a/fixtures/context.swift b/fixtures/context.swift
new file mode 100644
index 0000000..480127c
--- /dev/null
+++ b/fixtures/context.swift
@@ -0,0 +1,19 @@
+import GrainDescriptor
+
+// ./fixtures/context.swift --user-info '{"name" : "muukii"}'
+
+struct Parameter: Decodable {
+ var name: String
+}
+
+let parameter = try context.userInfo(Parameter.self)
+
+serialize(.json) {
+
+ GrainObject {
+ GrainMember("context") {
+ parameter.name
+ }
+ }
+
+}