swift-structured-data
外部由来の JSON / YAML / XML を Swift の型システムへ安全に変換するレイヤー
English | 日本語
swift-structured-data
A safe bridge that converts dynamic structured data from external systems (JSON and more) into Swift's type system.
Separates the "parse correctly" layer from the "convert to types" layer, bridging to Codable without losing numeric precision or ordering.
For the full design rationale, see DESIGN.md.
Features
- Precision-preserving number model — JSON numbers are kept as raw decimal text and converted lazily to the requested type
- Protocol-centric dependency design — consumers inject
any StructuredDecodingand never depend on a concrete parser - Single backbone for all formats — one custom
Decoder/Encoderimplementation, reused across every format - Two-tier access — dynamic
value.user.name.stringexploration alongside type-safedecode(_:) - Opt-in tolerant decoding per field —
@Default/@LossyArray/@LosslessValue - Streaming partial decode — extract in-progress state from an LLM token-by-token output
- Verified against the official conformance suite —
nst/JSONTestSuitebundled, coveringy_/n_/i_cases
Usage
Decode / Encode
import JSONParsing
struct Config: Codable { var retries: Int; var hosts: [String] }
let config = try JSONDecoder().decode(Config.self, from: data)
let encoded = try JSONEncoder().encode(config)
Inject a protocol (dependency inversion)
import StructuredDataCore // library depends only on Core
struct APIClient {
let decoder: any StructuredDecoding
func parse<T: Decodable>(_ type: T.Type, from data: Data) throws -> T {
try decoder.decode(type, from: data)
}
}
// Only the composition root (app) picks the concrete type
let client = APIClient(decoder: JSONDecoder())
Dynamic exploration
let value = try JSONParser().parse(data)
value.user.name.string // String?
value.items[0].id.int // Int?
value["count", as: Int.self] // Int?
Tolerant decoding
struct Settings: Codable {
@DefaultFalse var verbose: Bool
@DefaultEmptyArray<String> var tags: [String]
@LossyArray var ids: [Int] // discard malformed elements
@LosslessValue var port: Int // accepts "8080" or 8080
}
Streaming
var parser = StreamingJSONParser()
parser.consume(#"{"name":"Ad"#)
parser.snapshot().name.string // "Ad"
parser.consume(#"a"}"#)
parser.snapshot().name.string // "Ada"
Installation
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/no-problem-dev/swift-structured-data.git", from: "1.4.0"),
],
Then add the products you need:
.product(name: "StructuredDataCore", package: "swift-structured-data"),
.product(name: "JSONParsing", package: "swift-structured-data"),
.product(name: "YAMLParsing", package: "swift-structured-data"),
.product(name: "XMLCoding", package: "swift-structured-data"),
Modules
| Module | Role |
|---|---|
StructuredDataCore |
Protocols, neutral DOM, Decoder/Encoder backbone, property wrappers |
JSONParsing |
RFC 8259 parser/serializer, streaming |
YAMLParsing |
YAML 1.2 Core subset (block/flow, block scalars, multi-doc, Norway fix) |
XMLCoding |
XML tree parsing, declarative builder, correct escaping |
YAML does not support the full spec (anchors/aliases, tags, complex keys). For implementation status and test coverage see DESIGN.md.
License
MIT
同じカテゴリの OSS — LLM / AI
swift-llm-cloud
Swift PackageAnthropic / OpenAI / Gemini を束ねるマルチプロバイダー LLM クラウドクライアント
swift-llm-local
Swift PackageiOS / macOS のデバイス上でローカル LLM 推論を動かす Swift パッケージ
swift-llm-mcp
Swift Packageswift-llm-client 向けの MCP + ツール解決層。MCP サーバーと組み込みツールキットのアダプタ
swift-research-agent
Swift PackageWeb 検索・取得ツールと引用ゲートを備えたリサーチャー・エージェント
swift-media-agent
Swift Package画像・チャート・動画生成ツールとセッション単位のメディアストアを持つビジュアライザー・エージェント