From 333d4fc886038491db72af6052bee9a7eb0fefbc Mon Sep 17 00:00:00 2001 From: Stephan Boyer Date: Wed, 19 Jun 2024 15:58:51 -0700 Subject: [PATCH] Make some type signatures more permissive --- CHANGELOG.md | 5 + Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 5 +- examples/rust/src/main.rs | 20 +- examples/typescript/src/main.ts | 26 +-- .../typescript_node/src/assertions.ts | 7 +- .../typescript_web/src/assertions.ts | 7 +- src/generate_typescript.rs | 93 +++++++--- test_data/types.ts | 175 +++++++++++++----- 10 files changed, 237 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aca99a50..3be00e95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.12.1] - 2024-06-19 + +### Changed +- The TypeScript deserialization functions now have a more permissive type signature. + ## [0.12.0] - 2024-06-19 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 2ac7aca4..ec5cacbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "typical" -version = "0.12.0" +version = "0.12.1" dependencies = [ "clap", "colored", diff --git a/Cargo.toml b/Cargo.toml index 4fdac2c6..b8d642d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "typical" -version = "0.12.0" +version = "0.12.1" authors = ["Stephan Boyer "] edition = "2021" description = "Data interchange with algebraic data types." diff --git a/README.md b/README.md index 7cd5dec7..c2cd073f 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,9 @@ let message = SendEmailRequestOut { body: "It makes serialization easy and safe.".to_owned(), }; -let file = BufWriter::new(File::create(FILE_PATH)?); -message.serialize(file)?; +let mut file = BufWriter::new(File::create(REQUEST_FILE_PATH)?); +message.serialize(&mut file)?; +file.flush()?; ``` Another program could read the file and deserialize the message as follows: diff --git a/examples/rust/src/main.rs b/examples/rust/src/main.rs index c7df281e..8f0e1cfe 100644 --- a/examples/rust/src/main.rs +++ b/examples/rust/src/main.rs @@ -3,7 +3,7 @@ mod types; use { std::{ fs::{remove_file, File}, - io::{self, BufReader, BufWriter}, + io::{self, BufReader, BufWriter, Write}, }, types::{ types::{ @@ -16,7 +16,7 @@ use { const REQUEST_FILE_PATH: &str = "/tmp/request"; const RESPONSE_FILE_PATH: &str = "/tmp/response"; -fn write_to_file() -> io::Result<()> { +fn write_to_files() -> io::Result<()> { let request_message = SendEmailRequestOut { to: "typical@example.com".to_owned(), subject: "I love Typical!".to_owned(), @@ -25,14 +25,16 @@ fn write_to_file() -> io::Result<()> { let response_message = SendEmailResponseOut::Error("Example error".to_string()); - let request_file = BufWriter::new(File::create(REQUEST_FILE_PATH)?); - request_message.serialize(request_file)?; + let mut request_file = BufWriter::new(File::create(REQUEST_FILE_PATH)?); + request_message.serialize(&mut request_file)?; + request_file.flush()?; - let response_file = BufWriter::new(File::create(RESPONSE_FILE_PATH)?); - response_message.serialize(response_file) + let mut response_file = BufWriter::new(File::create(RESPONSE_FILE_PATH)?); + response_message.serialize(&mut response_file)?; + response_file.flush() } -fn read_from_file() -> io::Result<()> { +fn read_from_files() -> io::Result<()> { let request_file = BufReader::new(File::open(REQUEST_FILE_PATH)?); let request_message = SendEmailRequestIn::deserialize(request_file)?; @@ -52,8 +54,8 @@ fn read_from_file() -> io::Result<()> { } fn main() -> io::Result<()> { - write_to_file()?; - read_from_file()?; + write_to_files()?; + read_from_files()?; remove_file(REQUEST_FILE_PATH)?; remove_file(RESPONSE_FILE_PATH) } diff --git a/examples/typescript/src/main.ts b/examples/typescript/src/main.ts index 533eaa95..8d8f96d3 100644 --- a/examples/typescript/src/main.ts +++ b/examples/typescript/src/main.ts @@ -5,7 +5,7 @@ const requestFilePath = '/tmp/request'; const responseFilePath = '/tmp/response'; const { SendEmailRequest, SendEmailResponse } = Types; -function writeToFile(): void { +function writeToFiles(): void { const requestMessage = { to: 'typical@example.com', subject: 'I love Typical!', @@ -23,29 +23,15 @@ function writeToFile(): void { writeFileSync(responseFilePath, Buffer.from(responseArrayBuffer)); } -function readFromFile(): void { +function readFromFiles(): void { const requestFileContents = readFileSync(requestFilePath); - const requestMessage = SendEmailRequest.deserialize( - new DataView( - requestFileContents.buffer, - requestFileContents.byteOffset, - requestFileContents.byteLength, - ), - ); - + const requestMessage = SendEmailRequest.deserialize(requestFileContents); if (requestMessage instanceof Error) { throw requestMessage; } const responseFileContents = readFileSync(responseFilePath); - const responseMessage = SendEmailResponse.deserialize( - new DataView( - responseFileContents.buffer, - responseFileContents.byteOffset, - responseFileContents.byteLength, - ), - ); - + const responseMessage = SendEmailResponse.deserialize(responseFileContents); if (responseMessage instanceof Error) { throw responseMessage; } @@ -72,7 +58,7 @@ function readFromFile(): void { return undefined; // To satisfy ESLint's `consistent-return` rule } -writeToFile(); -readFromFile(); +writeToFiles(); +readFromFiles(); unlinkSync(requestFilePath); unlinkSync(responseFilePath); diff --git a/integration_tests/typescript_node/src/assertions.ts b/integration_tests/typescript_node/src/assertions.ts index b678e6cd..2beb53dd 100644 --- a/integration_tests/typescript_node/src/assertions.ts +++ b/integration_tests/typescript_node/src/assertions.ts @@ -15,7 +15,7 @@ try { export function assertMatch( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (dataView: DataView) => I, + deserialize: (bytes: ArrayBuffer) => I, actual: O, expected: unknown, ): void { @@ -27,14 +27,13 @@ export function assertMatch( console.log('Expected size of the serialized message:', actualSize); const arrayBuffer = serialize(actual); - const dataView = new DataView(arrayBuffer); deepStrictEqual(arrayBuffer.byteLength, actualSize); console.log('Bytes from serialization:', arrayBuffer); console.log('Size of the serialized message:', arrayBuffer.byteLength); writeFileSync(omnifilePath, Buffer.from(arrayBuffer), { flag: 'as' }); - const replica = deserialize(dataView); + const replica = deserialize(arrayBuffer); deepStrictEqual(replica, expected); console.log('Message deserialized from those bytes:', replica); @@ -44,7 +43,7 @@ export function assertMatch( export function assertRoundTrip( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (dataView: DataView) => I, + deserialize: (bytes: ArrayBuffer) => I, message: V, ): void { assertMatch(size, serialize, deserialize, message, message); diff --git a/integration_tests/typescript_web/src/assertions.ts b/integration_tests/typescript_web/src/assertions.ts index 458d49b9..3f8da32d 100644 --- a/integration_tests/typescript_web/src/assertions.ts +++ b/integration_tests/typescript_web/src/assertions.ts @@ -20,7 +20,7 @@ function deepStrictEqual(x: T, y: U): void { export function assertMatch( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (dataView: DataView) => I, + deserialize: (bytes: ArrayBuffer) => I, actual: O, expected: unknown, ): void { @@ -32,7 +32,6 @@ export function assertMatch( console.log('Expected size of the serialized message:', actualSize); const arrayBuffer = serialize(actual); - const dataView = new DataView(arrayBuffer); deepStrictEqual(arrayBuffer.byteLength, actualSize); console.log('Bytes from serialization:', arrayBuffer); console.log('Size of the serialized message:', arrayBuffer.byteLength); @@ -41,7 +40,7 @@ export function assertMatch( omnifileArray.set(typedArray, omnifileOffset); omnifileOffset += arrayBuffer.byteLength; - const replica = deserialize(dataView); + const replica = deserialize(arrayBuffer); deepStrictEqual(replica, expected); console.log('Message deserialized from those bytes:', replica); @@ -51,7 +50,7 @@ export function assertMatch( export function assertRoundTrip( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (dataView: DataView) => I, + deserialize: (bytes: ArrayBuffer) => I, message: V, ): void { assertMatch(size, serialize, deserialize, message, message); diff --git a/src/generate_typescript.rs b/src/generate_typescript.rs index f67aa526..6c32f28d 100644 --- a/src/generate_typescript.rs +++ b/src/generate_typescript.rs @@ -155,6 +155,21 @@ pub fn generate( /* eslint-disable */ +export type Deserializable = + | ArrayBuffer + | DataView + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array + | BigInt64Array + | BigUint64Array; + export function unreachable(x: never): never {{ return x; }} @@ -614,7 +629,13 @@ fn write_schema( writeln!(buffer)?; - write_serialize_function(buffer, indentation + 1, &declaration.name)?; + write_serialize_function( + buffer, + indentation + 1, + &declaration.variant, + &declaration.name, + &declaration.fields, + )?; writeln!(buffer)?; @@ -1001,7 +1022,13 @@ fn write_schema( writeln!(buffer)?; - write_serialize_function(buffer, indentation + 1, &declaration.name)?; + write_serialize_function( + buffer, + indentation + 1, + &declaration.variant, + &declaration.name, + &declaration.fields, + )?; writeln!(buffer)?; @@ -1452,29 +1479,35 @@ fn write_size_function( fn write_serialize_function( buffer: &mut T, indentation: usize, + declaration_variant: &schema::DeclarationVariant, name: &Identifier, + fields: &[schema::Field], ) -> Result<(), fmt::Error> { write_indentation(buffer, indentation)?; write!(buffer, "export function serialize(message: ")?; write_identifier(buffer, name, Pascal, Some(Out))?; writeln!(buffer, "): ArrayBuffer {{")?; - write_indentation(buffer, indentation + 1)?; - writeln!(buffer, "const messageAtlas = atlas(message);")?; - write_indentation(buffer, indentation + 1)?; - writeln!( - buffer, - "const arrayBuffer = \ - new ArrayBuffer((messageAtlas as {{ $size: number }}).$size);", - )?; - write_indentation(buffer, indentation + 1)?; - writeln!(buffer, "const dataView = new DataView(arrayBuffer);")?; - write_indentation(buffer, indentation + 1)?; - writeln!( - buffer, - "serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas);", - )?; - write_indentation(buffer, indentation + 1)?; - writeln!(buffer, "return arrayBuffer;")?; + if let (schema::DeclarationVariant::Choice, true) = (declaration_variant, fields.is_empty()) { + write_indentation(buffer, indentation + 1)?; + writeln!(buffer, "return unreachable(message);")?; + } else { + write_indentation(buffer, indentation + 1)?; + writeln!(buffer, "const messageAtlas = atlas(message);")?; + write_indentation(buffer, indentation + 1)?; + writeln!( + buffer, + "const arrayBuffer = new ArrayBuffer(messageAtlas.$size);", + )?; + write_indentation(buffer, indentation + 1)?; + writeln!(buffer, "const dataView = new DataView(arrayBuffer);")?; + write_indentation(buffer, indentation + 1)?; + writeln!( + buffer, + "serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas);", + )?; + write_indentation(buffer, indentation + 1)?; + writeln!(buffer, "return arrayBuffer;")?; + } write_indentation(buffer, indentation)?; writeln!(buffer, "}}") } @@ -1486,13 +1519,31 @@ fn write_deserialize_function( name: &Identifier, ) -> Result<(), fmt::Error> { write_indentation(buffer, indentation)?; - write!(buffer, "export function deserialize(dataView: DataView): ")?; + write!( + buffer, + "export function deserialize(bytes: Deserializable): ", + )?; write_identifier(buffer, name, Pascal, Some(In))?; writeln!(buffer, " | Error {{")?; write_indentation(buffer, indentation + 1)?; writeln!(buffer, "try {{")?; write_indentation(buffer, indentation + 2)?; - writeln!(buffer, "return deserializeUnsafe(dataView);")?; + writeln!(buffer, "if (bytes instanceof ArrayBuffer) {{")?; + write_indentation(buffer, indentation + 3)?; + writeln!(buffer, "return deserializeUnsafe(new DataView(bytes));")?; + write_indentation(buffer, indentation + 2)?; + writeln!(buffer, "}}")?; + write_indentation(buffer, indentation + 2)?; + writeln!(buffer, "if (bytes instanceof DataView) {{")?; + write_indentation(buffer, indentation + 3)?; + writeln!(buffer, "return deserializeUnsafe(bytes);")?; + write_indentation(buffer, indentation + 2)?; + writeln!(buffer, "}}")?; + write_indentation(buffer, indentation + 2)?; + writeln!( + buffer, + "return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength));", + )?; write_indentation(buffer, indentation + 1)?; writeln!(buffer, "}} catch (e) {{")?; write_indentation(buffer, indentation + 2)?; diff --git a/test_data/types.ts b/test_data/types.ts index f3421b16..805f7240 100644 --- a/test_data/types.ts +++ b/test_data/types.ts @@ -3,6 +3,21 @@ /* eslint-disable */ +export type Deserializable = + | ArrayBuffer + | DataView + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array + | BigInt64Array + | BigUint64Array; + export function unreachable(x: never): never { return x; } @@ -305,15 +320,21 @@ export namespace CircularDependency { export function serialize(message: StructFromBelowOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): StructFromBelowIn | Error { + export function deserialize(bytes: Deserializable): StructFromBelowIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -439,15 +460,21 @@ export namespace CircularDependency { export function serialize(message: StructFromAboveOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): StructFromAboveIn | Error { + export function deserialize(bytes: Deserializable): StructFromAboveIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -720,15 +747,21 @@ export namespace Comprehensive { export function serialize(message: LocalStructOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): LocalStructIn | Error { + export function deserialize(bytes: Deserializable): LocalStructIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -1041,15 +1074,21 @@ export namespace Comprehensive { export function serialize(message: FooOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): FooIn | Error { + export function deserialize(bytes: Deserializable): FooIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -8295,15 +8334,21 @@ export namespace Comprehensive { export function serialize(message: BarOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): BarIn | Error { + export function deserialize(bytes: Deserializable): BarIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -15264,15 +15309,21 @@ export namespace Degenerate { export function serialize(message: EmptyStructOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): EmptyStructIn | Error { + export function deserialize(bytes: Deserializable): EmptyStructIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -15337,16 +15388,18 @@ export namespace Degenerate { } export function serialize(message: EmptyChoiceOut): ArrayBuffer { - const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); - const dataView = new DataView(arrayBuffer); - serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); - return arrayBuffer; + return unreachable(message); } - export function deserialize(dataView: DataView): EmptyChoiceIn | Error { + export function deserialize(bytes: Deserializable): EmptyChoiceIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -15437,15 +15490,21 @@ export namespace SchemaEvolution { export function serialize(message: ExampleStructOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): ExampleStructIn | Error { + export function deserialize(bytes: Deserializable): ExampleStructIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -16055,15 +16114,21 @@ export namespace SchemaEvolution { export function serialize(message: ExampleChoiceOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): ExampleChoiceIn | Error { + export function deserialize(bytes: Deserializable): ExampleChoiceIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -16632,15 +16697,21 @@ export namespace SchemaEvolution { export function serialize(message: ExampleStructOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): ExampleStructIn | Error { + export function deserialize(bytes: Deserializable): ExampleStructIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -17327,15 +17398,21 @@ export namespace SchemaEvolution { export function serialize(message: ExampleChoiceOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): ExampleChoiceIn | Error { + export function deserialize(bytes: Deserializable): ExampleChoiceIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -17886,15 +17963,21 @@ export namespace SchemaEvolution { export function serialize(message: SingletonStructOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): SingletonStructIn | Error { + export function deserialize(bytes: Deserializable): SingletonStructIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; } @@ -18019,15 +18102,21 @@ export namespace SchemaEvolution { export function serialize(message: SingletonChoiceOut): ArrayBuffer { const messageAtlas = atlas(message); - const arrayBuffer = new ArrayBuffer((messageAtlas as { $size: number }).$size); + const arrayBuffer = new ArrayBuffer(messageAtlas.$size); const dataView = new DataView(arrayBuffer); serializeWithAtlasUnsafe(dataView, 0, message, messageAtlas); return arrayBuffer; } - export function deserialize(dataView: DataView): SingletonChoiceIn | Error { + export function deserialize(bytes: Deserializable): SingletonChoiceIn | Error { try { - return deserializeUnsafe(dataView); + if (bytes instanceof ArrayBuffer) { + return deserializeUnsafe(new DataView(bytes)); + } + if (bytes instanceof DataView) { + return deserializeUnsafe(bytes); + } + return deserializeUnsafe(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)); } catch (e) { return e as Error; }