Initial Commit.
This commit is contained in:
commit
92ac8e8263
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.DS_Store
|
||||
/.build
|
||||
/Packages
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.swiftpm/configuration/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
||||
|
||||
/.vscode
|
||||
11
.swift-format
Normal file
11
.swift-format
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 1,
|
||||
"lineLength": 100,
|
||||
"indentation": {
|
||||
"spaces": 4
|
||||
},
|
||||
"maximumBlankLines": 1,
|
||||
"respectsExistingLineBreaks": true,
|
||||
"lineBreakBeforeControlFlowKeywords": true,
|
||||
"lineBreakBeforeEachArgument": true
|
||||
}
|
||||
15
Package.resolved
Normal file
15
Package.resolved
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"originHash" : "d88be4258c389a35639a4f2bbde8f9f0c10823cb590d44070870e9cf382a9629",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "meta",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://git.aparoksha.dev/aparoksha/meta",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "ce9c5bf7d1e8da54d64515f3d0e0fa3b05ad4355"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
||||
39
Package.swift
Normal file
39
Package.swift
Normal file
@ -0,0 +1,39 @@
|
||||
// swift-tools-version: 6.0
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "meta-json",
|
||||
platforms: [
|
||||
.macOS(.v10_15)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "MetaJSON",
|
||||
targets: ["MetaJSON"]
|
||||
)
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://git.aparoksha.dev/aparoksha/meta", branch: "main")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "MetaJSON",
|
||||
dependencies: [
|
||||
.product(name: "Meta", package: "meta")
|
||||
],
|
||||
path: "Sources"
|
||||
|
||||
),
|
||||
.executableTarget(
|
||||
name: "Tests",
|
||||
dependencies: ["MetaJSON"],
|
||||
path: "Tests"
|
||||
),
|
||||
|
||||
],
|
||||
swiftLanguageModes: [
|
||||
.v5
|
||||
]
|
||||
)
|
||||
68
Sources/MetaJSON/State.swift
Normal file
68
Sources/MetaJSON/State.swift
Normal file
@ -0,0 +1,68 @@
|
||||
import Foundation
|
||||
import Meta
|
||||
|
||||
extension State where Value: Codable {
|
||||
|
||||
/// Initialize a property remembered between launches using a JSON file.
|
||||
/// - Parameters:
|
||||
/// - wrappedValue: The default value if no stored value exists.
|
||||
/// - stateID: Unique key for the value.
|
||||
/// - forceUpdates: Whether to force update all available views when modified.
|
||||
public init(
|
||||
wrappedValue: @autoclosure @escaping () -> Value,
|
||||
_ stateID: String,
|
||||
forceUpdates: Bool = false
|
||||
) {
|
||||
self.init(
|
||||
wrappedValue: {
|
||||
guard let data = try? Data(contentsOf: URL(fileURLWithPath: JSONDatabase.path)),
|
||||
let storage = try? JSONDecoder().decode([String: Data].self, from: data),
|
||||
let storedValueData = storage[stateID],
|
||||
let value = try? JSONDecoder().decode(Value.self, from: storedValueData)
|
||||
else {
|
||||
return wrappedValue()
|
||||
}
|
||||
return value
|
||||
},
|
||||
writeValue: { value in
|
||||
var storage: [String: Data] = [:]
|
||||
let url = URL(fileURLWithPath: JSONDatabase.path)
|
||||
|
||||
if let data = try? Data(contentsOf: url),
|
||||
let decoded = try? JSONDecoder().decode([String: Data].self, from: data)
|
||||
{
|
||||
storage = decoded
|
||||
}
|
||||
|
||||
if let encodedValue = try? JSONEncoder().encode(value) {
|
||||
storage[stateID] = encodedValue
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
|
||||
if let newData = try? encoder.encode(storage) {
|
||||
try? FileManager.default.createDirectory(
|
||||
at: url.deletingLastPathComponent(),
|
||||
withIntermediateDirectories: true
|
||||
)
|
||||
try? newData.write(to: url, options: .atomic)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
forceUpdates: forceUpdates
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum JSONDatabase {
|
||||
|
||||
/// The path to the JSON file.
|
||||
static var path = "./database.json"
|
||||
|
||||
/// Optionally allow customization of the path.
|
||||
public static func setPath(_ newPath: String) {
|
||||
self.path = newPath
|
||||
}
|
||||
}
|
||||
16
Tests/Test.swift
Normal file
16
Tests/Test.swift
Normal file
@ -0,0 +1,16 @@
|
||||
import Meta
|
||||
import MetaJSON
|
||||
|
||||
/// The test function.
|
||||
func main() {
|
||||
@State("test")
|
||||
var test = 0
|
||||
@State("other")
|
||||
var other = 3
|
||||
print(test)
|
||||
print(other)
|
||||
test = 1
|
||||
other = 0
|
||||
}
|
||||
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user