Skip to content

Repository files navigation

English | 日本語

swift-structured-data

One way to read external data into Swift, whatever format it arrives in.

Swift Platforms License

Your code asks for a value; it does not need to know whether that value came from JSON, YAML, or XML. Each format has its own parser, they all produce the same neutral value, and one Decoder backbone turns that value into your type. Changing the format your app reads is a change at one place.

Features

  • The format stays out of your call sites — inject any StructuredDecoding, and swapping JSON for YAML is a change at the composition root
  • One backbone for every format — a single Decoder/Encoder implementation, shared by all three parsers, so the three behave the same way
  • Two ways in — dynamic exploration with value.user.name.string, or type-safe decode(_:)
  • Tolerant decoding is opt-in, per field@Default, @LossyArray, @LosslessValue
  • Streaming partial decode — read in-progress state out of a token-by-token LLM response
  • Values survive the trip — a number is carried as its original text and converted only when a concrete type asks, so nothing is quietly rounded on the way in
  • Checked against the official conformance suitenst/JSONTestSuite is bundled, covering the y_, n_, and i_ cases

Quick Start

import JSONParsing

struct Config: Codable { var retries: Int; var hosts: [String] }

let config = try JSONDecoder().decode(Config.self, from: data)

Explore a payload whose shape you do not know yet — missing paths yield nil rather than throwing:

let value = try JSONParser().parse(data)
value.user.name.string          // String?
value.items[0].id.int           // Int?

Or accept messy input on the fields where you have decided to:

struct Settings: Codable {
    @DefaultFalse var verbose: Bool
    @LossyArray var ids: [Int]      // drop malformed elements instead of failing the whole decode
    @LosslessValue var port: Int     // accepts "8080" as well as 8080
}

Documentation

API reference and guides — including Getting Started and Modules, which covers what each parser accepts and rejects.

The design rationale, in Japanese, is in DESIGN.md.

Installation

// Package.swift
dependencies: [
    .package(url: "https://github.com/no-problem-dev/swift-structured-data.git", from: "3.0.0"),
]

Add the products you need. Each format module depends on StructuredDataCore; add it explicitly to any target that names its types directly, such as one that injects any StructuredDecoding:

.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"),

Requirements

  • iOS 17.0+ / macOS 14.0+ / tvOS 17.0+ / watchOS 10.0+ / visionOS 1.0+
  • Linux
  • Swift 6.2+

License

MIT — see LICENSE.

About

One way to read external data into Swift — JSON, YAML, and XML behind a single protocol, so the format stays out of your call sites

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages