My coworker Dan Steward and I, have been getting into the strongly typed nature of Swift and realizing that JSON is lacking in this regard. I think Swift needs its own strongly typed Data Definition format, that fixes shortcomings of JSON. We came up with this, any ideas or feedback?
Swift Data Format(SDF): A strictly typed data description format.
- Adopts much of Swift's syntax so should feel natural to Swift developers but different enough to not mistake for Swift code.
- Prevents errors that are common in JSON of malformed or invalid structures. Utilizes strict type checking.
- Does not specify
class
orstruct
that is up to the loading program. - Allows both swift style comments
- You can define a constant that can be read from a Swift file
- Easily decoded and encoded using Codable in your Swift code.
- Generates to binary
- Reminiscent of the the old Rez file format but more aligned with Swift. Equivalent tools to
Rez
andDeRez
would exist and constants could be exported for easy sharing in Swift code so there is only one place to change. - Alternative to JSON which would validate the schema before letting it be read.
- Editors could validate as code is typed.
- Definitions can be separate or in the same file.
- Allows definitions of own named entities that can be built up like you can with structs.
- Optionals are supported.
- Default values can be defined in the definition.
- Allows definitions, with
let
that later get evaluated. (I see no need for var). - Should support mathematical constructs so if you need to calculate a value 10 + 4 * 3 would be allowed.
- Supports the base Swift types (Int, String) etc
- Haven't thought about how protocols could be imported but might be an interesting direction.
- Associated values for Swift
enums
, I can't currently see how that would work, but interesting area to explore. - Enums would likely have to specify a type but open to ideas.
- Could eventually replace Storyboard XML, Xcode Project format, and Plist formats as prefered format and even the SPM Package format.
- Would need to be made cross platform to support use as data transfer format.
- Reference: OpenDDL (didn't feel Swifty enough).
Detailed example:
// Comments are supported
/*
this style comment allowed
*/
// NOTE THIS IS NOT SWIFT, it is a Swift like data definition language.
// Definitions
import OtherDefinitons // can put other definitions in separate files.
def Pet(
name: String
age: Int
legs: Int = 10 // default
)
enum Kind: String (
case employee
case manager = "Manager"
)
def Person(
kind: Kind,
height: Int,
age: Double,
name: String,
friends: [Person]
nice: Bool?
pets: [Pet]
)
def Vertex(
x: Float,
y: Float,
z: Float
)
def Color(
red: Double,
green: Double,
blue: Double,
alpha: Double = 1.0,
enum Predefined {
case yellow: Color(red: 0.0, green: 1.0, blue: 1.0)
case blue: Color(red: 0.0, green: 0.0, blue: 1.0)
case red: Color(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.4)
}
)
def Vehicle(
color: Color,
name: String
)
def People: [Person]
// instances
let george = Person(
kind: .employee,
height: 10,
age: 49,
name: "george",
nice: true,
friends = [john, paul, ringo]
pets: []
)
let john = Person(
kind: .manager,
height: 10,
age: 49,
name: "john",
friends: [george, paul, ringo],
nice: true,
pets: [ Pet(
name: "fluffy",
age: 10,
legs: 4
),
Pet(
name: "RaptorMax",
age: 12 // legs defaulted.
)
]
)
let paul = Person(
kind: .manager,
height: 10,
age: 49,
name: "Paul",
nice: true,
friends: [john, george, ringo]
pets: []
)
let ringo = Person(
kind: .employee,
height: 10,
age: 49,
name: "Ringo", // optional "nice" not declared here for example, not saying anything either way about example person.
friends: [george, paul, john]
pets: []
)
// can define using let or in line, 'let' does not output anything just defines it.
let vertex3 = Vertex(
x: 9.9, y: 2.9, z: 4.5
)
let verticies = [
Vertex(
x: 0.0,
y: 0.0,
z: 0.0
),
Vertex(
x: 10.0,
y: 10.0,
z: 10.0
),
vertex3
]
// generates objects into result file, nothing generated otherwise, kind of like how Playgrounds don't do
// anything unless you output result.
ringo
verticies
Vehicle(
color: .Predefined.yellow,
name: "Yellow Submarine"
)