jetstream 16.0.0

Jetstream is a RPC framework for Rust, based on the 9P protocol and QUIC.
Documentation
// JetStream WireFormat — Optional Encoding
// Copyright (c) 2024, Sevki <s@sevki.io>
// SPDX-License-Identifier: BSD-3-Clause

import Foundation

// r[impl jetstream.wireformat.option]
// r[impl jetstream.wireformat.swift.optional]

/// Helper to encode an Optional value using the wire format.
/// Since Swift doesn't allow direct protocol conformance on Optional generically
/// with associated type constraints, we provide free functions.
public enum OptionalCoding {
    public static func byteSize<T: WireFormat>(_ value: T?) -> UInt32 {
        switch value {
        case .none:
            return 1
        case .some(let inner):
            return 1 + inner.byteSize()
        }
    }

    public static func encode<T: WireFormat>(_ value: T?, writer: inout BinaryWriter) throws {
        switch value {
        case .none:
            writer.writeU8(0)
        case .some(let inner):
            writer.writeU8(1)
            try inner.encode(writer: &writer)
        }
    }

    public static func decode<T: WireFormat>(reader: inout BinaryReader) throws -> T? {
        let tag = try reader.readU8()
        switch tag {
        case 0:
            return nil
        case 1:
            return try T.decode(reader: &reader)
        default:
            throw WireFormatError.invalidOptionalTag(tag)
        }
    }
}

/// WireFormat conformance for Optional where Wrapped conforms to WireFormat.
extension Optional: WireFormat where Wrapped: WireFormat {
    public func byteSize() -> UInt32 {
        OptionalCoding.byteSize(self)
    }

    public func encode(writer: inout BinaryWriter) throws {
        try OptionalCoding.encode(self, writer: &writer)
    }

    public static func decode(reader: inout BinaryReader) throws -> Wrapped? {
        try OptionalCoding.decode(reader: &reader)
    }
}