Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
778a768
Update Package.swift for Swift 6 and macro support
colemancda Jul 18, 2026
971f6d4
Add Package.resolved
colemancda Jul 18, 2026
bf28189
Update TLVCodable protocols
colemancda Jul 18, 2026
c9f02b6
Update TLVTypeCode
colemancda Jul 18, 2026
7c2c9b6
Update TLVCodingKey
colemancda Jul 18, 2026
82de471
Update TLVItem
colemancda Jul 18, 2026
d312400
Add TLVContainer
colemancda Jul 18, 2026
640fda7
Add TLVCodable conformances for primitive types
colemancda Jul 18, 2026
8ac6c6b
Add Data shim for platforms without Foundation
colemancda Jul 18, 2026
7ab3c76
Add TLVCodable conformances for UUID and Date
colemancda Jul 18, 2026
ff40479
Add TLVCodable macro declaration
colemancda Jul 18, 2026
ced36ac
Add TLVCodableMacro implementation
colemancda Jul 18, 2026
31c1c48
Add macro error type
colemancda Jul 18, 2026
3c2f37a
Add compiler plugin entry point
colemancda Jul 18, 2026
4b22d9d
Remove TLVEncoder
colemancda Jul 18, 2026
f1ec6ef
Remove TLVDecoder
colemancda Jul 18, 2026
8c67fbd
Remove TLV formatting options
colemancda Jul 18, 2026
07751f4
Remove DataConvertible
colemancda Jul 18, 2026
85bbc98
Remove Integer extensions
colemancda Jul 18, 2026
da1a6f1
Remove LinuxMain
colemancda Jul 18, 2026
8197146
Update unit tests
colemancda Jul 18, 2026
d9cc9a0
Add macro expansion tests
colemancda Jul 18, 2026
eccae30
Update GitHub CI
colemancda Jul 18, 2026
d59e2fa
Update README
colemancda Jul 18, 2026
a96ff3f
Use FoundationEssentials in TLVCodable protocols
colemancda Jul 18, 2026
f6f6fc8
Use FoundationEssentials in TLVItem
colemancda Jul 18, 2026
0b27ceb
Use FoundationEssentials in TLVContainer
colemancda Jul 18, 2026
9a9e251
Use FoundationEssentials in primitive conformances
colemancda Jul 18, 2026
6487a53
Use FoundationEssentials for UUID and Date conformances
colemancda Jul 18, 2026
30939af
Update Data shim availability for FoundationEssentials
colemancda Jul 18, 2026
15aac9b
Run Embedded Swift CI on Linux
colemancda Jul 18, 2026
34911f3
Remove Buildroot CI
colemancda Jul 18, 2026
e94854b
Remove Swift ARM CI
colemancda Jul 18, 2026
d5087ed
Remove SwiftWASM CI
colemancda Jul 18, 2026
43390e3
Merge branch 'master' into feature/embedded
colemancda Jul 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .github/workflows/swift-wasm.yml

This file was deleted.

15 changes: 15 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 84 additions & 9 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
// swift-tools-version:5.1
// swift-tools-version:6.0
import PackageDescription
import CompilerPluginSupport
import class Foundation.ProcessInfo

// get environment variables
let environment = ProcessInfo.processInfo.environment
let dynamicLibrary = environment["SWIFT_BUILD_DYNAMIC_LIBRARY"] != nil
let enableMacros = environment["SWIFTPM_ENABLE_MACROS"] != "0"
let buildDocs = environment["BUILDING_FOR_DOCUMENTATION_GENERATION"] != nil

// force building as dynamic library
let dynamicLibrary = ProcessInfo.processInfo.environment["SWIFT_BUILD_DYNAMIC_LIBRARY"] != nil
let libraryType: PackageDescription.Product.Library.LibraryType? = dynamicLibrary ? .dynamic : nil

var package = Package(
name: "TLVCoding",
platforms: [
.macOS(.v10_15),
.iOS(.v13),
.watchOS(.v6),
.tvOS(.v13),
],
products: [
.library(
name: "TLVCoding",
Expand All @@ -17,8 +29,7 @@ var package = Package(
],
targets: [
.target(
name: "TLVCoding",
path: "./Sources"
name: "TLVCoding"
),
.testTarget(
name: "TLVCodingTests",
Expand All @@ -27,12 +38,76 @@ var package = Package(
]
)

// SwiftPM command plugins are only supported by Swift version 5.6 and later.
#if swift(>=5.6)
let buildDocs = ProcessInfo.processInfo.environment["BUILDING_FOR_DOCUMENTATION_GENERATION"] != nil
// SwiftPM plugins
if buildDocs {
package.dependencies += [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
.package(
url: "https://github.com/swiftlang/swift-docc-plugin.git",
from: "1.4.5"
)
]
}

if enableMacros {
let version: Version
#if swift(>=6.3)
version = "603.0.1"
#elseif swift(>=6.2)
version = "602.0.0"
#elseif swift(>=6.1)
version = "601.0.1"
#else
version = "600.0.1"
#endif
package.targets[0].swiftSettings = [
.define("SWIFTPM_ENABLE_MACROS")
]
package.dependencies += [
.package(
url: "https://github.com/swiftlang/swift-syntax.git",
from: version
)
]
package.targets += [
.macro(
name: "TLVCodingMacros",
dependencies: [
.product(
name: "SwiftSyntaxMacros",
package: "swift-syntax"
),
.product(
name: "SwiftCompilerPlugin",
package: "swift-syntax"
)
]
)
]
package.targets[0].dependencies += [
"TLVCodingMacros"
]
package.targets += [
.testTarget(
name: "TLVCodingMacrosTests",
dependencies: [
"TLVCodingMacros",
.product(
name: "SwiftSyntaxMacros",
package: "swift-syntax"
),
.product(
name: "SwiftSyntaxMacroExpansion",
package: "swift-syntax"
),
.product(
name: "SwiftParser",
package: "swift-syntax"
),
.product(
name: "SwiftSyntaxMacrosTestSupport",
package: "swift-syntax"
)
]
)
]
}
#endif
96 changes: 89 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,96 @@
# TLVCoding

[![Build Status](https://travis-ci.org/PureSwift/TLVCoding.svg?branch=master)](https://travis-ci.org/PureSwift/TLVCoding)
[![Swift](https://github.com/PureSwift/TLVCoding/actions/workflows/swift.yml/badge.svg)](https://github.com/PureSwift/TLVCoding/actions/workflows/swift.yml)

TLV8 (Type-Length-Value) Coder library
TLV8 (Type-Length-Value) Coder library, compatible with [Embedded Swift](https://github.com/swiftlang/swift/tree/main/docs/EmbeddedSwift).

# See Also
Types are encoded and decoded explicitly via `TLVCodable` — either with conformances generated by the `@TLVCodable` macro, or written by hand. The library does not depend on `Codable` runtime machinery or Foundation, so it can be used on bare-metal targets.

## Usage

### Macro-generated conformance

```swift
import TLVCoding

@TLVCodable
struct ProvisioningState: Equatable {

var state: State

var result: Result

enum CodingKeys: UInt8, TLVCodingKey {
case state = 0x01
case result = 0x02
}
}

let value = ProvisioningState(state: .provisioning, result: .success)
let data = value.tlvData // Data([0x01, 0x01, 0x01, 0x02, 0x01, 0x01])
let decoded = ProvisioningState(tlvData: data)
```

If no `CodingKeys` enum is declared, one is generated with sequential type codes in property declaration order.

### Hand-written conformance

The same conformance can be written manually (e.g. for Embedded Swift or custom binary layouts):

```swift
extension ProvisioningState: TLVCodable {

init?(tlvData: Data) {
guard let container = TLVContainer(data: tlvData),
let state = container.decode(State.self, forKey: CodingKeys.state),
let result = container.decode(Result.self, forKey: CodingKeys.result)
else { return nil }
self.state = state
self.result = result
}

var tlvData: Data {
var container = TLVContainer()
container.encode(state, forKey: CodingKeys.state)
container.encode(result, forKey: CodingKeys.result)
return container.data
}
}
```

Types with a custom binary layout can skip `TLVContainer` entirely and produce their payload directly:

```swift
extension Version: TLVCodable {

init?(tlvData: Data) {
guard tlvData.count == 3 else { return nil }
self.major = tlvData[0]
self.minor = tlvData[1]
self.patch = tlvData[2]
}

var tlvData: Data {
Data([major, minor, patch])
}
}
```

### Embedded Swift

Macros are disabled under Embedded Swift (write conformances by hand) and the swift-syntax dependency can be skipped entirely with the `SWIFTPM_ENABLE_MACROS` environment variable:

```bash
SWIFTPM_ENABLE_MACROS=0 swift build --target TLVCoding \
--triple armv7em-none-none-eabi \
-Xswiftc -enable-experimental-feature -Xswiftc Embedded \
-Xswiftc -wmo
```

On platforms without Foundation, a minimal `Data` type is provided by the library.

## See Also

- [CoreModel](https://github.com/PureSwift/CoreModel) - Swift ORM with the same explicit coding and macro design
- [BluetoothLinux](https://github.com/PureSwift/BluetoothLinux) - Pure Swift Linux Bluetooth Stack
- [GATT](https://github.com/PureSwift/GATT) - Bluetooth Generic Attribute Profile (GATT) for Swift
- [SwiftFoundation](https://github.com/PureSwift/SwiftFoundation) - Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library.
- [Cacao](https://github.com/PureSwift/Cacao) - Pure Swift Cross-platform UIKit
- [Silica](https://github.com/PureSwift/Silica) - Pure Swift CoreGraphics (Quartz2D) implementation
- [Predicate](https://github.com/PureSwift/Predicate) - Pure Swift Predicate implementation
108 changes: 0 additions & 108 deletions Sources/CodingKey.swift

This file was deleted.

Loading
Loading