From 12ba47a281644b35cac7ea9c582d36c6f5b621b5 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 13 Nov 2024 19:37:48 +0100 Subject: [PATCH 01/18] remove servicepoint_binding_cs --- Cargo.toml | 1 - crates/servicepoint_binding_cs/Cargo.toml | 20 - crates/servicepoint_binding_cs/README.md | 65 - .../servicepoint_binding_cs/ServicePoint.sln | 28 - .../ServicePoint/BindGen/ServicePoint.g.cs | 1463 ----------------- .../ServicePoint/BitVec.cs | 88 - .../ServicePoint/Bitmap.cs | 100 -- .../ServicePoint/BrightnessGrid.cs | 100 -- .../ServicePoint/Command.cs | 129 -- .../ServicePoint/Connection.cs | 40 - .../ServicePoint/Constants.cs | 24 - .../ServicePoint/Cp437Grid.cs | 131 -- .../ServicePoint/GlobalUsings.cs | 1 - .../ServicePoint/Packet.cs | 36 - .../ServicePoint/ServicePoint.csproj | 57 - .../ServicePoint/ServicePointExtensions.cs | 16 - .../ServicePoint/SpNativeInstance.cs | 51 - crates/servicepoint_binding_cs/build.rs | 39 - .../examples/lang_cs/Program.cs | 20 - .../examples/lang_cs/lang_cs.csproj | 15 - crates/servicepoint_binding_cs/src/lib.rs | 1 - 21 files changed, 2425 deletions(-) delete mode 100644 crates/servicepoint_binding_cs/Cargo.toml delete mode 100644 crates/servicepoint_binding_cs/README.md delete mode 100644 crates/servicepoint_binding_cs/ServicePoint.sln delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/BitVec.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Command.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Connection.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Constants.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/Packet.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs delete mode 100644 crates/servicepoint_binding_cs/build.rs delete mode 100644 crates/servicepoint_binding_cs/examples/lang_cs/Program.cs delete mode 100644 crates/servicepoint_binding_cs/examples/lang_cs/lang_cs.csproj delete mode 100644 crates/servicepoint_binding_cs/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 9bc62fc..ddc5168 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ resolver = "2" members = [ "crates/servicepoint", "crates/servicepoint_binding_c", - "crates/servicepoint_binding_cs", "crates/servicepoint_binding_c/examples/lang_c" ] diff --git a/crates/servicepoint_binding_cs/Cargo.toml b/crates/servicepoint_binding_cs/Cargo.toml deleted file mode 100644 index 01282ac..0000000 --- a/crates/servicepoint_binding_cs/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "servicepoint_binding_cs" -version.workspace = true -edition = "2021" -publish = false -readme = "README.md" - -[lib] -crate-type = ["cdylib"] -test = false - -[build-dependencies] -csbindgen = "1.9.3" - -[dependencies] -servicepoint_binding_c = { version = "0.11.0", path = "../servicepoint_binding_c" } -servicepoint = { version = "0.11.0", path = "../servicepoint" } - -[lints] -workspace = true diff --git a/crates/servicepoint_binding_cs/README.md b/crates/servicepoint_binding_cs/README.md deleted file mode 100644 index bd2107a..0000000 --- a/crates/servicepoint_binding_cs/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# ServicePoint - -In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wall. It is called "Service Point -Display" or "Airport Display". -This crate contains C# bindings for the `servicepoint` library, enabling users to parse, encode and send packets to this display via UDP. - -## Examples - -```csharp -using ServicePoint; - -// using statement calls Dispose() on scope exit, which frees unmanaged instances -using var connection = Connection.Open("127.0.0.1:2342"); -using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight); - -while (true) -{ - pixels.Fill(true); - connection.Send(Command.BitmapLinearWin(0, 0, pixels.Clone())); - Thread.Sleep(5000); - - pixels.Fill(false); - connection.Send(Command.BitmapLinearWin(0, 0, pixels.Clone())); - Thread.Sleep(5000); -} -``` - -A full example including project files is available as part of this crate. - -## Note on stability - -This library is still in early development. -You can absolutely use it, and it works, but expect minor breaking changes with every version bump. - -## Installation - -NuGet packages are not a good way to distribute native projects ([relevant issue](https://github.com/dotnet/sdk/issues/33845)). -Because of that, there is no NuGet package you can use directly. -Including this repository as a submodule and building from source is the recommended way of using the library. - -```bash -git submodule add https://github.com/cccb/servicepoint.git -git commit -m "add servicepoint submodule" -``` - -You can now reference `servicepoint-bindings-cs/src/ServicePoint.csproj` in your project. -The rust library will automatically be built. - -Please provide more information in the form of an issue if you need the build to copy a different library file for your platform. - -## Notes on differences to rust library - -Uses C bindings internally to provide a similar API to rust. Things to keep in mind: - -- You will get a `NullPointerException` when trying to call a method where the native instance has been consumed already (e.g. when `Send`ing a command instance twice). Send a clone instead of the original if you want to keep using it. -- Some lower-level APIs _will_ panic in native code when used improperly. - Example: manipulating the `Span` of an object after freeing the instance. -- C# specifics are documented in the library. Use the rust documentation for everything else. Naming and semantics are the same apart from CamelCase instead of kebab_case. -- You will only get rust backtraces in debug builds of the native code. -- F# is not explicitly tested. If there are usability or functionality problems, please open an issue. -- Reading and writing to instances concurrently is not safe. Only reading concurrently is safe. - -## Everything else - -Look at the main project [README](https://github.com/cccb/servicepoint/blob/main/README.md) for further information. diff --git a/crates/servicepoint_binding_cs/ServicePoint.sln b/crates/servicepoint_binding_cs/ServicePoint.sln deleted file mode 100644 index c4d9165..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "ServicePoint/ServicePoint.csproj", "{70EFFA3F-012A-4518-9627-466BEAE4252E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang-cs", "examples/lang_cs/lang_cs.csproj", "{DA3B8B6E-993A-47DA-844B-F92AF520FF59}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{C2F8EC4A-2426-4DC3-990F-C43810B183F5}" - ProjectSection(SolutionItems) = preProject - ..\..\shell.nix = ..\..\shell.nix - ..\..\.envrc = ..\..\.envrc - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {70EFFA3F-012A-4518-9627-466BEAE4252E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {70EFFA3F-012A-4518-9627-466BEAE4252E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {70EFFA3F-012A-4518-9627-466BEAE4252E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {70EFFA3F-012A-4518-9627-466BEAE4252E}.Release|Any CPU.Build.0 = Release|Any CPU - {DA3B8B6E-993A-47DA-844B-F92AF520FF59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DA3B8B6E-993A-47DA-844B-F92AF520FF59}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DA3B8B6E-993A-47DA-844B-F92AF520FF59}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DA3B8B6E-993A-47DA-844B-F92AF520FF59}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs deleted file mode 100644 index 8f41ab4..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ /dev/null @@ -1,1463 +0,0 @@ -// -// This code is generated by csbindgen. -// DON'T CHANGE THIS DIRECTLY. -// -#pragma warning disable CS8500 -#pragma warning disable CS8981 -using System; -using System.Runtime.InteropServices; - - -namespace ServicePoint.BindGen -{ - public static unsafe partial class NativeMethods - { - const string __DllName = "servicepoint_binding_c"; - - public const byte SP_BRIGHTNESS_MIN = 0; - public const byte SP_BRIGHTNESS_MAX = 11; - public const byte SP_BRIGHTNESS_LEVELS = 12; - public const nuint SP_TILE_SIZE = 8; - public const nuint SP_TILE_WIDTH = 56; - public const nuint SP_TILE_HEIGHT = 20; - - - /// - /// Creates a new [SPBitmap] with the specified dimensions. - /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. - /// - /// # Panics - /// - /// - when the width is not dividable by 8 - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); - - /// - /// Loads a [SPBitmap] with the specified dimensions from the provided data. - /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - when the dimensions and data size do not match exactly. - /// - when the width is not dividable by 8 - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory location of at least `data_length` bytes in size. - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); - - /// - /// Clones a [SPBitmap]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); - - /// - /// Deallocates a [SPBitmap]. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not used concurrently or after bitmap call - /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - /// [SPCommand]: [crate::SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_free(Bitmap* bitmap); - - /// - /// Gets the current value at the specified position in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - `x` and `y`: position of the cell to read - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); - - /// - /// Sets the value of the specified position in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: instance to write to - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// returns: old value of the cell - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Sets the state of all pixels in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: instance to write to - /// - `value`: the value to set all pixels to - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Gets the width in pixels of the [SPBitmap] instance. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_width(Bitmap* bitmap); - - /// - /// Gets the height in pixels of the [SPBitmap] instance. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_height(Bitmap* bitmap); - - /// - /// Gets an unsafe reference to the data of the [SPBitmap] instance. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); - - /// - /// Creates a new [SPBitVec] instance. - /// - /// # Arguments - /// - /// - `size`: size in bits. - /// - /// returns: [SPBitVec] with all bits set to false. Will never return NULL. - /// - /// # Panics - /// - /// - when `size` is not divisible by 8. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_new(nuint size); - - /// - /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. - /// - /// returns: [SPBitVec] instance containing data. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory location of at least `data_length` - /// bytes in size. - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); - - /// - /// Clones a [SPBitVec]. - /// - /// returns: new [SPBitVec] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); - - /// - /// Deallocates a [SPBitVec]. - /// - /// # Panics - /// - /// - when `but_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - /// [SPCommand]: [crate::SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_free(BitVec* bit_vec); - - /// - /// Gets the value of a bit from the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to read from - /// - `index`: the bit index to read - /// - /// returns: value of the bit - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); - - /// - /// Sets the value of a bit in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `index`: the bit index to edit - /// - `value`: the value to set the bit to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Sets the value of all bits in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `value`: the value to set all bits to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Gets the length of the [SPBitVec] in bits. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitvec_len(BitVec* bit_vec); - - /// - /// Returns true if length is 0. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); - - /// - /// Gets an unsafe reference to the data of the [SPBitVec] instance. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// ## Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); - - /// - /// Creates a new [SPBrightnessGrid] with the specified dimensions. - /// - /// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_brightness_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_new(nuint width, nuint height); - - /// - /// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. - /// - /// returns: new [SPBrightnessGrid] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - when the provided `data_length` does not match `height` and `width` - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory location of at least `data_length` - /// bytes in size. - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_brightness_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_load(nuint width, nuint height, byte* data, nuint data_length); - - /// - /// Clones a [SPBrightnessGrid]. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - /// returns: new [SPBrightnessGrid] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - `brightness_grid` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_brightness_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_clone(BrightnessGrid* brightness_grid); - - /// - /// Deallocates a [SPBrightnessGrid]. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - `brightness_grid` is not used concurrently or after this call - /// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - /// [SPCommand]: [crate::SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_free(BrightnessGrid* brightness_grid); - - /// - /// Gets the current value at the specified position. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - `x` and `y`: position of the cell to read - /// - /// returns: value at position - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - When accessing `x` or `y` out of bounds. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - `brightness_grid` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_brightness_grid_get(BrightnessGrid* brightness_grid, nuint x, nuint y); - - /// - /// Sets the value of the specified position in the [SPBrightnessGrid]. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to write to - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// returns: old value of the cell - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - When accessing `x` or `y` out of bounds. - /// - When providing an invalid brightness value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - `brightness_grid` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_set(BrightnessGrid* brightness_grid, nuint x, nuint y, byte value); - - /// - /// Sets the value of all cells in the [SPBrightnessGrid]. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to write to - /// - `value`: the value to set all cells to - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - When providing an invalid brightness value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - `brightness_grid` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_fill(BrightnessGrid* brightness_grid, byte value); - - /// - /// Gets the width of the [SPBrightnessGrid] instance. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - /// returns: width - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_brightness_grid_width(BrightnessGrid* brightness_grid); - - /// - /// Gets the height of the [SPBrightnessGrid] instance. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - /// returns: height - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_brightness_grid_height(BrightnessGrid* brightness_grid); - - /// - /// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance. - /// - /// # Arguments - /// - /// - `brightness_grid`: instance to read from - /// - /// returns: slice of bytes underlying the `brightness_grid`. - /// - /// # Panics - /// - /// - when `brightness_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `brightness_grid` points to a valid [SPBrightnessGrid] - /// - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); - - /// - /// Tries to turn a [SPPacket] into a [SPCommand]. - /// - /// The packet is deallocated in the process. - /// - /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. - /// - /// # Panics - /// - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - [SPPacket] points to a valid instance of [SPPacket] - /// - [SPPacket] is not used concurrently or after this call - /// - the result is checked for NULL - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_try_from_packet(Packet* packet); - - /// - /// Clones a [SPCommand] instance. - /// - /// returns: new [SPCommand] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `command` points to a valid instance of [SPCommand] - /// - `command` is not written to concurrently - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clone(Command* command); - - /// - /// Set all pixels to the off state. - /// - /// Does not affect brightness. - /// - /// Returns: a new [servicepoint::Command::Clear] instance. Will never return NULL. - /// - /// # Examples - /// - /// ```C - /// sp_connection_send_command(connection, sp_command_clear()); - /// ``` - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clear(); - - /// - /// Kills the udp daemon on the display, which usually results in a restart. - /// - /// Please do not send this in your normal program flow. - /// - /// Returns: a new [servicepoint::Command::HardReset] instance. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_hard_reset(); - - /// - /// A yet-to-be-tested command. - /// - /// Returns: a new [servicepoint::Command::FadeOut] instance. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_fade_out(); - - /// - /// Set the brightness of all tiles to the same value. - /// - /// Returns: a new [servicepoint::Command::Brightness] instance. Will never return NULL. - /// - /// # Panics - /// - /// - When the provided brightness value is out of range (0-11). - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_brightness(byte brightness); - - /// - /// Set the brightness of individual tiles in a rectangular area of the display. - /// - /// The passed [SPBrightnessGrid] gets consumed. - /// - /// Returns: a new [servicepoint::Command::CharBrightness] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `grid` points to a valid instance of [SPBrightnessGrid] - /// - `grid` is not used concurrently or after this call - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid); - - /// - /// Set pixel data starting at the pixel offset on screen. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [servicepoint::Command::BitmapLinear] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to an and-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to an or-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [servicepoint::Command::BitmapLinearOr] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to a xor-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [servicepoint::Command::BitmapLinearXor] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Show text on the screen. - /// - /// The passed [SPCp437Grid] gets consumed. - /// - /// Returns: a new [servicepoint::Command::Cp437Data] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `grid` is null - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `grid` points to a valid instance of [SPCp437Grid] - /// - `grid` is not used concurrently or after this call - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid); - - /// - /// Sets a window of pixels to the specified values. - /// - /// The passed [SPBitmap] gets consumed. - /// - /// Returns: a new [servicepoint::Command::BitmapLinearWin] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bitmap` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid instance of [SPBitmap] - /// - `bitmap` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, Bitmap* bitmap, CompressionCode compression_code); - - /// - /// Deallocates a [SPCommand]. - /// - /// # Examples - /// - /// ```C - /// SPCommand c = sp_command_clear(); - /// sp_command_free(c); - /// ``` - /// - /// # Panics - /// - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `command` points to a valid [SPCommand] - /// - `command` is not used concurrently or after this call - /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] - /// - [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_command_free(Command* command); - - /// - /// Creates a new instance of [SPConnection]. - /// - /// returns: NULL if connection fails, or connected instance - /// - /// # Panics - /// - /// - when `host` is null or an invalid host - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_connection_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Connection* sp_connection_open(byte* host); - - /// - /// Sends a [SPPacket] to the display using the [SPConnection]. - /// - /// The passed `packet` gets consumed. - /// - /// returns: true in case of success - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `packet` points to a valid instance of [SPPacket] - /// - `packet` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); - - /// - /// Sends a [SPCommand] to the display using the [SPConnection]. - /// - /// The passed `command` gets consumed. - /// - /// returns: true in case of success - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `command` points to a valid instance of [SPPacket] - /// - `command` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_command(Connection* connection, Command* command); - - /// - /// Closes and deallocates a [SPConnection]. - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid [SPConnection] - /// - `connection` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_connection_free(Connection* connection); - - /// - /// Creates a new [SPCp437Grid] with the specified dimensions. - /// - /// returns: [SPCp437Grid] initialized to 0. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_cp437_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_new(nuint width, nuint height); - - /// - /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - when the provided `data_length` does not match `height` and `width` - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory location of at least `data_length` - /// bytes in size. - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_cp437_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); - - /// - /// Clones a [SPCp437Grid]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_cp437_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_clone(Cp437Grid* cp437_grid); - - /// - /// Deallocates a [SPCp437Grid]. - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not used concurrently or after cp437_grid call - /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - /// [SPCommand]: [crate::SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_free(Cp437Grid* cp437_grid); - - /// - /// Gets the current value at the specified position. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to read from - /// - `x` and `y`: position of the cell to read - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_cp437_grid_get(Cp437Grid* cp437_grid, nuint x, nuint y); - - /// - /// Sets the value of the specified position in the [SPCp437Grid]. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to write to - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// returns: old value of the cell - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPBitVec] - /// - `cp437_grid` is not written to or read from concurrently - /// - /// [SPBitVec]: [crate::SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_set(Cp437Grid* cp437_grid, nuint x, nuint y, byte value); - - /// - /// Sets the value of all cells in the [SPCp437Grid]. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to write to - /// - `value`: the value to set all cells to - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_fill(Cp437Grid* cp437_grid, byte value); - - /// - /// Gets the width of the [SPCp437Grid] instance. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to read from - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_width(Cp437Grid* cp437_grid); - - /// - /// Gets the height of the [SPCp437Grid] instance. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to read from - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_height(Cp437Grid* cp437_grid); - - /// - /// Gets an unsafe reference to the data of the [SPCp437Grid] instance. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `cp437_grid` is NULL - /// - /// ## Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); - - /// - /// Turns a [SPCommand] into a [SPPacket]. - /// The [SPCommand] gets consumed. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - [SPCommand] points to a valid instance of [SPCommand] - /// - [SPCommand] is not used concurrently or after this call - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_from_command(Command* command); - - /// - /// Tries to load a [SPPacket] from the passed array with the specified length. - /// - /// returns: NULL in case of an error, pointer to the allocated packet otherwise - /// - /// # Panics - /// - /// - when `data` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory region of at least `length` bytes - /// - `data` is not written to concurrently - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_try_load(byte* data, nuint length); - - /// - /// Clones a [SPPacket]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_clone(Packet* packet); - - /// - /// Deallocates a [SPPacket]. - /// - /// # Panics - /// - /// - when `sp_packet_free` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_packet_free(Packet* packet); - - - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Bitmap - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BitVec - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BrightnessGrid - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct ByteSlice - { - public byte* start; - public nuint length; - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Command - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Connection - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Cp437Grid - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Packet - { - } - - - public enum CompressionCode : ushort - { - Uncompressed = 0, - Zlib = 26490, - Bzip2 = 25210, - Lzma = 27770, - Zstd = 31347, - } - - -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs deleted file mode 100644 index ab697e0..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs +++ /dev/null @@ -1,88 +0,0 @@ -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class BitVec : SpNativeInstance -{ - public static BitVec New(int size) - { - unsafe - { - return new BitVec(NativeMethods.sp_bitvec_new((nuint)size)); - } - } - - public static BitVec Load(Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new BitVec(NativeMethods.sp_bitvec_load(bytesPtr, (nuint)bytes.Length)); - } - } - } - - public BitVec Clone() - { - unsafe - { - return new BitVec(NativeMethods.sp_bitvec_clone(Instance)); - } - } - - public bool this[int index] - { - get - { - unsafe - { - return NativeMethods.sp_bitvec_get(Instance, (nuint)index); - } - } - set - { - unsafe - { - NativeMethods.sp_bitvec_set(Instance, (nuint)index, value); - } - } - } - - public void Fill(bool value) - { - unsafe - { - NativeMethods.sp_bitvec_fill(Instance, value); - } - } - - public int Length - { - get - { - unsafe - { - return (int)NativeMethods.sp_bitvec_len(Instance); - } - } - } - - public Span Data - { - get - { - unsafe - { - var slice = NativeMethods.sp_bitvec_unsafe_data_ref(Instance); - return new Span(slice.start, (int)slice.length); - } - } - } - - private unsafe BitVec(BindGen.BitVec* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_bitvec_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs deleted file mode 100644 index 6747483..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs +++ /dev/null @@ -1,100 +0,0 @@ -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class Bitmap : SpNativeInstance -{ - public static Bitmap New(int width, int height) - { - unsafe - { - return new Bitmap(NativeMethods.sp_bitmap_new((nuint)width, (nuint)height)); - } - } - - public static Bitmap Load(int width, int height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new Bitmap(NativeMethods.sp_bitmap_load((nuint)width, (nuint)height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public Bitmap Clone() - { - unsafe - { - return new Bitmap(NativeMethods.sp_bitmap_clone(Instance)); - } - } - - public bool this[int x, int y] - { - get - { - unsafe - { - return NativeMethods.sp_bitmap_get(Instance, (nuint)x, (nuint)y); - } - } - set - { - unsafe - { - NativeMethods.sp_bitmap_set(Instance, (nuint)x, (nuint)y, value); - } - } - } - - public void Fill(bool value) - { - unsafe - { - NativeMethods.sp_bitmap_fill(Instance, value); - } - } - - public int Width - { - get - { - unsafe - { - return (int)NativeMethods.sp_bitmap_width(Instance); - } - } - } - - public int Height - { - get - { - unsafe - { - return (int)NativeMethods.sp_bitmap_height(Instance); - } - } - } - - public Span Data - { - get - { - unsafe - { - var slice = NativeMethods.sp_bitmap_unsafe_data_ref(Instance); - return new Span(slice.start, (int)slice.length); - } - } - } - - private unsafe Bitmap(BindGen.Bitmap* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_bitmap_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs b/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs deleted file mode 100644 index 53970b5..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs +++ /dev/null @@ -1,100 +0,0 @@ -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class BrightnessGrid : SpNativeInstance -{ - public static BrightnessGrid New(int width, int height) - { - unsafe - { - return new BrightnessGrid(NativeMethods.sp_brightness_grid_new((nuint)width, (nuint)height)); - } - } - - public static BrightnessGrid Load(int width, int height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new BrightnessGrid(NativeMethods.sp_brightness_grid_load((nuint)width, (nuint)height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public BrightnessGrid Clone() - { - unsafe - { - return new BrightnessGrid(NativeMethods.sp_brightness_grid_clone(Instance)); - } - } - - public byte this[int x, int y] - { - get - { - unsafe - { - return NativeMethods.sp_brightness_grid_get(Instance, (nuint)x, (nuint)y); - } - } - set - { - unsafe - { - NativeMethods.sp_brightness_grid_set(Instance, (nuint)x, (nuint)y, value); - } - } - } - - public void Fill(byte value) - { - unsafe - { - NativeMethods.sp_brightness_grid_fill(Instance, value); - } - } - - public int Width - { - get - { - unsafe - { - return (int)NativeMethods.sp_brightness_grid_width(Instance); - } - } - } - - public int Height - { - get - { - unsafe - { - return (int)NativeMethods.sp_brightness_grid_height(Instance); - } - } - } - - public Span Data - { - get - { - unsafe - { - var slice = NativeMethods.sp_brightness_grid_unsafe_data_ref(Instance); - return new Span(slice.start, (int)slice.length); - } - } - } - - private unsafe BrightnessGrid(BindGen.BrightnessGrid* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_brightness_grid_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/Command.cs b/crates/servicepoint_binding_cs/ServicePoint/Command.cs deleted file mode 100644 index b62d511..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Command.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class Command : SpNativeInstance -{ - public static bool TryFromPacket(Packet packet, [MaybeNullWhen(false)] out Command command) - { - unsafe - { - var result = NativeMethods.sp_command_try_from_packet(packet.Into()); - if (result == null) - { - command = null; - return false; - } - - command = new Command(result); - return true; - } - } - - public Command Clone() - { - unsafe - { - return new Command(NativeMethods.sp_command_clone(Instance)); - } - } - - public static Command Clear() - { - unsafe - { - return new Command(NativeMethods.sp_command_clear()); - } - } - - public static Command HardReset() - { - unsafe - { - return new Command(NativeMethods.sp_command_hard_reset()); - } - } - - public static Command FadeOut() - { - unsafe - { - return new Command(NativeMethods.sp_command_fade_out()); - } - } - - public static Command Brightness(byte brightness) - { - unsafe - { - return new Command(NativeMethods.sp_command_brightness(brightness)); - } - } - - public static Command CharBrightness(int x, int y, BrightnessGrid grid) - { - unsafe - { - return new Command(NativeMethods.sp_command_char_brightness((ushort)x, (ushort)y, grid.Into())); - } - } - - public static Command BitmapLinear(int offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - NativeMethods.sp_command_bitmap_linear((ushort)offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearAnd(int offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - NativeMethods.sp_command_bitmap_linear_and((ushort)offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearOr(int offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - NativeMethods.sp_command_bitmap_linear_or((ushort)offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearXor(int offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - NativeMethods.sp_command_bitmap_linear_xor((ushort)offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearWin(int x, int y, Bitmap bitmap, CompressionCode compression) - { - unsafe - { - return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, bitmap.Into(), compression)); - } - } - - public static Command Cp437Data(int x, int y, Cp437Grid byteGrid) - { - unsafe - { - return new Command(NativeMethods.sp_command_cp437_data((ushort)x, (ushort)y, byteGrid.Into())); - } - } - - private unsafe Command(BindGen.Command* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_command_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/Connection.cs b/crates/servicepoint_binding_cs/ServicePoint/Connection.cs deleted file mode 100644 index eff3b32..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Connection.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Text; -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class Connection : SpNativeInstance -{ - public static Connection Open(string host) - { - unsafe - { - fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host)) - { - return new Connection(NativeMethods.sp_connection_open(bytePtr)); - } - } - } - - public bool Send(Packet packet) - { - unsafe - { - return NativeMethods.sp_connection_send_packet(Instance, packet.Into()); - } - } - - public bool Send(Command command) - { - unsafe - { - return NativeMethods.sp_connection_send_command(Instance, command.Into()); - } - } - - private protected override unsafe void Free() => NativeMethods.sp_connection_free(Instance); - - private unsafe Connection(BindGen.Connection* instance) : base(instance) - { - } -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs deleted file mode 100644 index 14ea940..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs +++ /dev/null @@ -1,24 +0,0 @@ -using ServicePoint.BindGen; - -namespace ServicePoint; - -public static class Constants -{ - /// size of a single tile in one dimension - public const nuint TileSize = NativeMethods.SP_TILE_SIZE; - - /// tile count in the x-direction - public const nuint TileWidth = NativeMethods.SP_TILE_WIDTH; - - /// tile count in the y-direction - public const nuint TileHeight = NativeMethods.SP_TILE_SIZE; - - /// screen width in pixels - public const nuint PixelWidth = TileWidth * TileSize; - - /// screen height in pixels - public const nuint PixelHeight = TileHeight * TileSize; - - /// pixel count on whole screen - public const nuint PixelCount = PixelWidth * PixelHeight; -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs b/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs deleted file mode 100644 index 905828b..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System.Text; -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class Cp437Grid : SpNativeInstance -{ - public static Cp437Grid New(int width, int height) - { - unsafe - { - return new Cp437Grid(NativeMethods.sp_cp437_grid_new((nuint)width, (nuint)height)); - } - } - - public static Cp437Grid Load(int width, int height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new Cp437Grid(NativeMethods.sp_cp437_grid_load((nuint)width, (nuint)height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public Cp437Grid Clone() - { - unsafe - { - return new Cp437Grid(NativeMethods.sp_cp437_grid_clone(Instance)); - } - } - - public byte this[int x, int y] - { - get - { - unsafe - { - return NativeMethods.sp_cp437_grid_get(Instance, (nuint)x, (nuint)y); - } - } - set - { - unsafe - { - NativeMethods.sp_cp437_grid_set(Instance, (nuint)x, (nuint)y, value); - } - } - } - - public string this[int y] - { - set - { - var width = Width; - ArgumentOutOfRangeException.ThrowIfGreaterThan(value.Length, width); - - var x = 0; - for (; x < value.Length; x++) - this[x, y] = (byte)value[x]; - - for (; x < width; x++) - this[x, y] = 0; - } - - get - { - var sb = new StringBuilder(); - for (int x = 0; x < Width; x++) - { - var val = this[x, y]; - if (val == 0) - break; - sb.Append((char)val); - } - - return sb.ToString(); - } - } - - public void Fill(byte value) - { - unsafe - { - NativeMethods.sp_cp437_grid_fill(Instance, value); - } - } - - public int Width - { - get - { - unsafe - { - return (int)NativeMethods.sp_cp437_grid_width(Instance); - } - } - } - - public int Height - { - get - { - unsafe - { - return (int)NativeMethods.sp_cp437_grid_height(Instance); - } - } - } - - public Span Data - { - get - { - unsafe - { - var slice = NativeMethods.sp_cp437_grid_unsafe_data_ref(Instance); - return new Span(slice.start, (int)slice.length); - } - } - } - - private unsafe Cp437Grid(BindGen.Cp437Grid* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_cp437_grid_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs b/crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs deleted file mode 100644 index 911a584..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using System; \ No newline at end of file diff --git a/crates/servicepoint_binding_cs/ServicePoint/Packet.cs b/crates/servicepoint_binding_cs/ServicePoint/Packet.cs deleted file mode 100644 index 24c2c18..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/Packet.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using ServicePoint.BindGen; - -namespace ServicePoint; - -public sealed class Packet : SpNativeInstance -{ - public static Packet FromCommand(Command command) - { - unsafe - { - return new Packet(NativeMethods.sp_packet_from_command(command.Into())); - } - } - - public static bool TryFromBytes(Span bytes, [MaybeNullWhen(false)] out Packet packet) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - var instance = NativeMethods.sp_packet_try_load(bytesPtr, (nuint)bytes.Length); - packet = instance == null - ? null - : new Packet(instance); - return packet != null; - } - } - } - - private unsafe Packet(BindGen.Packet* instance) : base(instance) - { - } - - private protected override unsafe void Free() => NativeMethods.sp_packet_free(Instance); -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj deleted file mode 100644 index e806186..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net8.0 - disable - enable - true - - true - - - - ServicePoint - 0.11.0 - Repository Authors - None - ServicePoint - CCCB - - C# bindings for the rust crate servicepoint. You will need a suitable native shared library to use this. - For documentation, see the rust documentation: https://docs.rs/servicepoint/latest/servicepoint/. - Note that this library is still in early development. Breaking changes are expected before 1.0 is released. - - README.md - true - - - - - - - - - - - - - - - - libservicepoint_binding_c.so - - - - - libservicepoint_binding_c.so - - - - - - - - - - - diff --git a/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs b/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs deleted file mode 100644 index 0e569ff..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace ServicePoint; - -public static class ServicePointExtensions -{ - public static Packet IntoPacket(this Command command) - { - return Packet.FromCommand(command); - } - - public static bool TryIntoCommand(this Packet packet, [MaybeNullWhen(false)] out Command command) - { - return Command.TryFromPacket(packet, out command); - } -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs b/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs deleted file mode 100644 index b6c492e..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace ServicePoint; - -public abstract class SpNativeInstance - : IDisposable - where T : unmanaged -{ - private unsafe T* _instance; - - internal unsafe T* Instance - { - get - { - if (_instance == null) - throw new NullReferenceException("instance is null"); - return _instance; - } - } - - private protected unsafe SpNativeInstance(T* instance) - { - ArgumentNullException.ThrowIfNull(instance); - _instance = instance; - } - - private protected abstract void Free(); - - internal unsafe T* Into() - { - var instance = _instance; - _instance = null; - return instance; - } - - private unsafe void ReleaseUnmanagedResources() - { - if (_instance != null) - Free(); - _instance = null; - } - - public void Dispose() - { - ReleaseUnmanagedResources(); - GC.SuppressFinalize(this); - } - - ~SpNativeInstance() - { - ReleaseUnmanagedResources(); - } -} diff --git a/crates/servicepoint_binding_cs/build.rs b/crates/servicepoint_binding_cs/build.rs deleted file mode 100644 index 8caf589..0000000 --- a/crates/servicepoint_binding_cs/build.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Build script generating the C# code needed to call methods from the `servicepoint` C library. - -use std::fs; - -fn main() { - println!("cargo::rerun-if-changed=../servicepoint_binding_c/src"); - println!("cargo::rerun-if-changed=build.rs"); - - let mut builder = csbindgen::Builder::default(); - - let mut paths = fs::read_dir("../servicepoint_binding_c/src").unwrap() - .map(|x| x.unwrap().path()) - .collect::>(); - paths.sort(); - - for path in paths { - println!("cargo:rerun-if-changed={}", path.display()); - builder = builder.input_extern_file(path); - } - - builder - .csharp_dll_name("servicepoint_binding_c") - .csharp_namespace("ServicePoint.BindGen") - .csharp_use_nint_types(true) - .csharp_class_accessibility("public") - .csharp_generate_const_filter(|_| true) - .csharp_type_rename(move |name| { - if name.len() > 2 - && name.starts_with("SP") - && name.chars().nth(2).unwrap().is_uppercase() - { - name[2..].to_string() - } else { - name - } - }) - .generate_csharp_file("ServicePoint/BindGen/ServicePoint.g.cs") - .unwrap(); -} diff --git a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs b/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs deleted file mode 100644 index 89c0eef..0000000 --- a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -using ServicePoint; -using CompressionCode = ServicePoint.BindGen.CompressionCode; - -using var connection = Connection.Open("127.0.0.1:2342"); - -connection.Send(Command.Clear().IntoPacket()); -connection.Send(Command.Brightness(128).IntoPacket()); - -using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight); - -for (var offset = 0; offset < int.MaxValue; offset++) -{ - pixels.Fill(false); - - for (var y = 0; y < pixels.Height; y++) - pixels[(y + offset) % Constants.PixelWidth, y] = true; - - connection.Send(Command.BitmapLinearWin(0, 0, pixels.Clone(), CompressionCode.Lzma).IntoPacket()); - Thread.Sleep(14); -} diff --git a/crates/servicepoint_binding_cs/examples/lang_cs/lang_cs.csproj b/crates/servicepoint_binding_cs/examples/lang_cs/lang_cs.csproj deleted file mode 100644 index e83a385..0000000 --- a/crates/servicepoint_binding_cs/examples/lang_cs/lang_cs.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - net8.0 - lang_cs - enable - enable - - - - - - - diff --git a/crates/servicepoint_binding_cs/src/lib.rs b/crates/servicepoint_binding_cs/src/lib.rs deleted file mode 100644 index c7bcac6..0000000 --- a/crates/servicepoint_binding_cs/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -//! This crate is intentionally left empty. Only the build script is relevant here. From 07a1b8810cb754db83c78bc2d51f7887b31802ec Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 2 Nov 2024 23:15:54 +0100 Subject: [PATCH 02/18] basics for uniffi --- .gitignore | 2 - Cargo.toml | 3 +- crates/servicepoint_binding_uniffi/Cargo.toml | 49 + .../generate-bindings.sh | 19 + .../libraries/csharp/.gitignore | 2 + .../csharp/ServicePoint.Example/.gitignore | 2 + .../csharp/ServicePoint.Example/Program.cs | 5 + .../ServicePoint.Example.csproj | 15 + .../ServicePoint.Tests.csproj | 27 + .../csharp/ServicePoint.Tests/UnitTest1.cs | 12 + .../csharp/ServicePoint/ServicePoint.csproj | 53 + .../servicepoint_binding_uniffi.cs | 1077 +++++++++++++++++ .../libraries/csharp/csharp.sln | 34 + .../src/bin/uniffi-bindgen-cs.rs | 3 + .../src/bin/uniffi-bindgen.rs | 3 + .../src/command.rs | 20 + .../src/connection.rs | 23 + crates/servicepoint_binding_uniffi/src/lib.rs | 4 + .../servicepoint_binding_uniffi/uniffi.toml | 3 + 19 files changed, 1353 insertions(+), 3 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/Cargo.toml create mode 100755 crates/servicepoint_binding_uniffi/generate-bindings.sh create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/.gitignore create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/ServicePoint.Example.csproj create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ServicePoint.Tests.csproj create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/csharp.sln create mode 100644 crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-cs.rs create mode 100644 crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs create mode 100644 crates/servicepoint_binding_uniffi/src/command.rs create mode 100644 crates/servicepoint_binding_uniffi/src/connection.rs create mode 100644 crates/servicepoint_binding_uniffi/src/lib.rs create mode 100644 crates/servicepoint_binding_uniffi/uniffi.toml diff --git a/.gitignore b/.gitignore index dc1e685..8792323 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ target .idea out -bin -obj .direnv .envrc result diff --git a/Cargo.toml b/Cargo.toml index ddc5168..9eae2e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,8 @@ resolver = "2" members = [ "crates/servicepoint", "crates/servicepoint_binding_c", - "crates/servicepoint_binding_c/examples/lang_c" + "crates/servicepoint_binding_c/examples/lang_c", + "crates/servicepoint_binding_uniffi" ] [workspace.package] diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml new file mode 100644 index 0000000..5ba77a5 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "servicepoint_binding_uniffi" +version.workspace = true +publish = false +edition = "2021" +license = "GPL-3.0-or-later" +description = "C bindings for the servicepoint crate." +homepage = "https://docs.rs/crate/servicepoint_binding_c" +repository = "https://github.com/cccb/servicepoint" +#readme = "README.md" + +[lib] +crate-type = ["cdylib"] + +[build-dependencies] +uniffi = { version = "0.25.0" , features = [ "build" ] } + +[dependencies] +uniffi = { version = "0.25.0" } +thiserror = "1.0.66" + +[dependencies.servicepoint] +version = "0.11.0" +path = "../servicepoint" +features = ["all_compressions"] + +[dependencies.uniffi-bindgen-cs] +git="https://github.com/NordSecurity/uniffi-bindgen-cs" +# tag="v0.8.3+v0.25.0" +rev="f68639fbc720b50ebe561ba75c66c84dc456bdce" +optional=true + +[lints] +#workspace = true + +[package.metadata.docs.rs] +all-features = true + +[[bin]] +name = "uniffi-bindgen" +required-features = ["uniffi/cli"] + +[[bin]] +name = "uniffi-bindgen-cs" +required-features= ["cs"] + +[features] +default = [] +cs = ["dep:uniffi-bindgen-cs"] diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh new file mode 100755 index 0000000..97ad72e --- /dev/null +++ b/crates/servicepoint_binding_uniffi/generate-bindings.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set +x + +cargo build --release + +SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +TARGETPATH="$(realpath $SCRIPTPATH/../../target/release/)" +SERVICEPOINT_SO="$TARGETPATH/libservicepoint_binding_uniffi.so" +CONFIG_TOML="$(realpath $SCRIPTPATH/../uniffi.toml)" + +BINDGEN="cargo run --features=uniffi/cli --bin uniffi-bindgen -- " +BINDGEN_CS="cargo run --features=cs --bin uniffi-bindgen-cs -- " +COMMON_ARGS="--library $SERVICEPOINT_SO" + +${BINDGEN} generate $COMMON_ARGS --language python --out-dir libraries/python +${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir libraries/kotlin +${BINDGEN} generate $COMMON_ARGS --language swift --out-dir libraries/swift +${BINDGEN_CS} $COMMON_ARGS --out-dir libraries/csharp/ServicePoint diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/.gitignore b/crates/servicepoint_binding_uniffi/libraries/csharp/.gitignore new file mode 100644 index 0000000..1746e32 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore new file mode 100644 index 0000000..1746e32 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs new file mode 100644 index 0000000..edca01c --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs @@ -0,0 +1,5 @@ +using ServicePoint; + +var connection = new Connection(""); + +var clear = new Clear(); diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/ServicePoint.Example.csproj b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/ServicePoint.Example.csproj new file mode 100644 index 0000000..3e99664 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/ServicePoint.Example.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + ServicePoint.Example + disable + enable + + + + + + + diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ServicePoint.Tests.csproj b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ServicePoint.Tests.csproj new file mode 100644 index 0000000..50500b6 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ServicePoint.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + disable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs new file mode 100644 index 0000000..46991d7 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs @@ -0,0 +1,12 @@ +using ServicePoint; + +namespace ServicePoint.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + Assert.Throws(() => new Connection("")); + } +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj new file mode 100644 index 0000000..5b7dc28 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj @@ -0,0 +1,53 @@ + + + + net8.0 + disable + enable + true + + + + ServicePoint + 0.10.0 + Repository Authors + None + ServicePoint + CCCB + + C# bindings for the rust crate servicepoint. You will need a suitable native shared library to use this. + For documentation, see the rust documentation: https://docs.rs/servicepoint/latest/servicepoint/. + Note that this library is still in early development. Breaking changes are expected before 1.0 is released. + + README.md + true + + + + + + + + + + + + + + libservicepoint_binding_uniffi.so + + + + + libservicepoint_binding_uniffi.so + + + + + + + + + + + diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs new file mode 100644 index 0000000..5e90f6c --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -0,0 +1,1077 @@ +// +// This file was generated by uniffi-bindgen-cs v0.8.3+v0.25.0 +// See https://github.com/NordSecurity/uniffi-bindgen-cs for more information. +// + +#nullable enable + + + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +namespace ServicePoint; + + + +// This is a helper for safely working with byte buffers returned from the Rust code. +// A rust-owned buffer is represented by its capacity, its current length, and a +// pointer to the underlying data. + +[StructLayout(LayoutKind.Sequential)] +internal struct RustBuffer { + public int capacity; + public int len; + public IntPtr data; + + public static RustBuffer Alloc(int size) { + return _UniffiHelpers.RustCall((ref RustCallStatus status) => { + var buffer = _UniFFILib.ffi_servicepoint_binding_uniffi_rustbuffer_alloc(size, ref status); + if (buffer.data == IntPtr.Zero) { + throw new AllocationException($"RustBuffer.Alloc() returned null data pointer (size={size})"); + } + return buffer; + }); + } + + public static void Free(RustBuffer buffer) { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.ffi_servicepoint_binding_uniffi_rustbuffer_free(buffer, ref status); + }); + } + + public static BigEndianStream MemoryStream(IntPtr data, int length) { + unsafe { + return new BigEndianStream(new UnmanagedMemoryStream((byte*)data.ToPointer(), length)); + } + } + + public BigEndianStream AsStream() { + unsafe { + return new BigEndianStream(new UnmanagedMemoryStream((byte*)data.ToPointer(), len)); + } + } + + public BigEndianStream AsWriteableStream() { + unsafe { + return new BigEndianStream(new UnmanagedMemoryStream((byte*)data.ToPointer(), capacity, capacity, FileAccess.Write)); + } + } +} + +// This is a helper for safely passing byte references into the rust code. +// It's not actually used at the moment, because there aren't many things that you +// can take a direct pointer to managed memory, and if we're going to copy something +// then we might as well copy it into a `RustBuffer`. But it's here for API +// completeness. + +[StructLayout(LayoutKind.Sequential)] +internal struct ForeignBytes { + public int length; + public IntPtr data; +} + + +// The FfiConverter interface handles converter types to and from the FFI +// +// All implementing objects should be public to support external types. When a +// type is external we need to import it's FfiConverter. +internal abstract class FfiConverter { + // Convert an FFI type to a C# type + public abstract CsType Lift(FfiType value); + + // Convert C# type to an FFI type + public abstract FfiType Lower(CsType value); + + // Read a C# type from a `ByteBuffer` + public abstract CsType Read(BigEndianStream stream); + + // Calculate bytes to allocate when creating a `RustBuffer` + // + // This must return at least as many bytes as the write() function will + // write. It can return more bytes than needed, for example when writing + // Strings we can't know the exact bytes needed until we the UTF-8 + // encoding, so we pessimistically allocate the largest size possible (3 + // bytes per codepoint). Allocating extra bytes is not really a big deal + // because the `RustBuffer` is short-lived. + public abstract int AllocationSize(CsType value); + + // Write a C# type to a `ByteBuffer` + public abstract void Write(CsType value, BigEndianStream stream); + + // Lower a value into a `RustBuffer` + // + // This method lowers a value into a `RustBuffer` rather than the normal + // FfiType. It's used by the callback interface code. Callback interface + // returns are always serialized into a `RustBuffer` regardless of their + // normal FFI type. + public RustBuffer LowerIntoRustBuffer(CsType value) { + var rbuf = RustBuffer.Alloc(AllocationSize(value)); + try { + var stream = rbuf.AsWriteableStream(); + Write(value, stream); + rbuf.len = Convert.ToInt32(stream.Position); + return rbuf; + } catch { + RustBuffer.Free(rbuf); + throw; + } + } + + // Lift a value from a `RustBuffer`. + // + // This here mostly because of the symmetry with `lowerIntoRustBuffer()`. + // It's currently only used by the `FfiConverterRustBuffer` class below. + protected CsType LiftFromRustBuffer(RustBuffer rbuf) { + var stream = rbuf.AsStream(); + try { + var item = Read(stream); + if (stream.HasRemaining()) { + throw new InternalException("junk remaining in buffer after lifting, something is very wrong!!"); + } + return item; + } finally { + RustBuffer.Free(rbuf); + } + } +} + +// FfiConverter that uses `RustBuffer` as the FfiType +internal abstract class FfiConverterRustBuffer: FfiConverter { + public override CsType Lift(RustBuffer value) { + return LiftFromRustBuffer(value); + } + public override RustBuffer Lower(CsType value) { + return LowerIntoRustBuffer(value); + } +} + + +// A handful of classes and functions to support the generated data structures. +// This would be a good candidate for isolating in its own ffi-support lib. +// Error runtime. +[StructLayout(LayoutKind.Sequential)] +struct RustCallStatus { + public sbyte code; + public RustBuffer error_buf; + + public bool IsSuccess() { + return code == 0; + } + + public bool IsError() { + return code == 1; + } + + public bool IsPanic() { + return code == 2; + } +} + +// Base class for all uniffi exceptions +public class UniffiException: Exception { + public UniffiException(): base() {} + public UniffiException(string message): base(message) {} +} + +public class UndeclaredErrorException: UniffiException { + public UndeclaredErrorException(string message): base(message) {} +} + +public class PanicException: UniffiException { + public PanicException(string message): base(message) {} +} + +public class AllocationException: UniffiException { + public AllocationException(string message): base(message) {} +} + +public class InternalException: UniffiException { + public InternalException(string message): base(message) {} +} + +public class InvalidEnumException: InternalException { + public InvalidEnumException(string message): base(message) { + } +} + +public class UniffiContractVersionException: UniffiException { + public UniffiContractVersionException(string message): base(message) { + } +} + +public class UniffiContractChecksumException: UniffiException { + public UniffiContractChecksumException(string message): base(message) { + } +} + +// Each top-level error class has a companion object that can lift the error from the call status's rust buffer +interface CallStatusErrorHandler where E: Exception { + E Lift(RustBuffer error_buf); +} + +// CallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR +class NullCallStatusErrorHandler: CallStatusErrorHandler { + public static NullCallStatusErrorHandler INSTANCE = new NullCallStatusErrorHandler(); + + public UniffiException Lift(RustBuffer error_buf) { + RustBuffer.Free(error_buf); + return new UndeclaredErrorException("library has returned an error not declared in UNIFFI interface file"); + } +} + +// Helpers for calling Rust +// In practice we usually need to be synchronized to call this safely, so it doesn't +// synchronize itself +class _UniffiHelpers { + public delegate void RustCallAction(ref RustCallStatus status); + public delegate U RustCallFunc(ref RustCallStatus status); + + // Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err + public static U RustCallWithError(CallStatusErrorHandler errorHandler, RustCallFunc callback) + where E: UniffiException + { + var status = new RustCallStatus(); + var return_value = callback(ref status); + if (status.IsSuccess()) { + return return_value; + } else if (status.IsError()) { + throw errorHandler.Lift(status.error_buf); + } else if (status.IsPanic()) { + // when the rust code sees a panic, it tries to construct a rustbuffer + // with the message. but if that code panics, then it just sends back + // an empty buffer. + if (status.error_buf.len > 0) { + throw new PanicException(FfiConverterString.INSTANCE.Lift(status.error_buf)); + } else { + throw new PanicException("Rust panic"); + } + } else { + throw new InternalException($"Unknown rust call status: {status.code}"); + } + } + + // Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err + public static void RustCallWithError(CallStatusErrorHandler errorHandler, RustCallAction callback) + where E: UniffiException + { + _UniffiHelpers.RustCallWithError(errorHandler, (ref RustCallStatus status) => { + callback(ref status); + return 0; + }); + } + + // Call a rust function that returns a plain value + public static U RustCall(RustCallFunc callback) { + return _UniffiHelpers.RustCallWithError(NullCallStatusErrorHandler.INSTANCE, callback); + } + + // Call a rust function that returns a plain value + public static void RustCall(RustCallAction callback) { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + callback(ref status); + return 0; + }); + } +} + + +// Big endian streams are not yet available in dotnet :'( +// https://github.com/dotnet/runtime/issues/26904 + +class StreamUnderflowException: Exception { + public StreamUnderflowException() { + } +} + +class BigEndianStream { + Stream stream; + public BigEndianStream(Stream stream) { + this.stream = stream; + } + + public bool HasRemaining() { + return (stream.Length - stream.Position) > 0; + } + + public long Position { + get => stream.Position; + set => stream.Position = value; + } + + public void WriteBytes(byte[] value) { + stream.Write(value, 0, value.Length); + } + + public void WriteByte(byte value) { + stream.WriteByte(value); + } + + public void WriteUShort(ushort value) { + stream.WriteByte((byte)(value >> 8)); + stream.WriteByte((byte)value); + } + + public void WriteUInt(uint value) { + stream.WriteByte((byte)(value >> 24)); + stream.WriteByte((byte)(value >> 16)); + stream.WriteByte((byte)(value >> 8)); + stream.WriteByte((byte)value); + } + + public void WriteULong(ulong value) { + WriteUInt((uint)(value >> 32)); + WriteUInt((uint)value); + } + + public void WriteSByte(sbyte value) { + stream.WriteByte((byte)value); + } + + public void WriteShort(short value) { + WriteUShort((ushort)value); + } + + public void WriteInt(int value) { + WriteUInt((uint)value); + } + + public void WriteFloat(float value) { + unsafe { + WriteInt(*((int*)&value)); + } + } + + public void WriteLong(long value) { + WriteULong((ulong)value); + } + + public void WriteDouble(double value) { + WriteLong(BitConverter.DoubleToInt64Bits(value)); + } + + public byte[] ReadBytes(int length) { + CheckRemaining(length); + byte[] result = new byte[length]; + stream.Read(result, 0, length); + return result; + } + + public byte ReadByte() { + CheckRemaining(1); + return Convert.ToByte(stream.ReadByte()); + } + + public ushort ReadUShort() { + CheckRemaining(2); + return (ushort)(stream.ReadByte() << 8 | stream.ReadByte()); + } + + public uint ReadUInt() { + CheckRemaining(4); + return (uint)(stream.ReadByte() << 24 + | stream.ReadByte() << 16 + | stream.ReadByte() << 8 + | stream.ReadByte()); + } + + public ulong ReadULong() { + return (ulong)ReadUInt() << 32 | (ulong)ReadUInt(); + } + + public sbyte ReadSByte() { + return (sbyte)ReadByte(); + } + + public short ReadShort() { + return (short)ReadUShort(); + } + + public int ReadInt() { + return (int)ReadUInt(); + } + + public float ReadFloat() { + unsafe { + int value = ReadInt(); + return *((float*)&value); + } + } + + public long ReadLong() { + return (long)ReadULong(); + } + + public double ReadDouble() { + return BitConverter.Int64BitsToDouble(ReadLong()); + } + + private void CheckRemaining(int length) { + if (stream.Length - stream.Position < length) { + throw new StreamUnderflowException(); + } + } +} + +// Contains loading, initialization code, +// and the FFI Function declarations in a com.sun.jna.Library. + + +// This is an implementation detail which will be called internally by the public API. +static class _UniFFILib { + static _UniFFILib() { + _UniFFILib.uniffiCheckContractApiVersion(); + _UniFFILib.uniffiCheckApiChecksums(); + + } + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_clear( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ClearSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_clear_new(ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_command( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_connection( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ConnectionSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new(RustBuffer @host,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_alloc(int @size,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_from_bytes(ForeignBytes @bytes,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rustbuffer_free(RustBuffer @buf,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_reserve(RustBuffer @buf,int @additional,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_continuation_callback_set(IntPtr @callback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_u8(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_u8(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_u8(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern byte ffi_servicepoint_binding_uniffi_rust_future_complete_u8(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_i8(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_i8(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_i8(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte ffi_servicepoint_binding_uniffi_rust_future_complete_i8(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_u16(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_u16(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_u16(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort ffi_servicepoint_binding_uniffi_rust_future_complete_u16(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_i16(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_i16(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_i16(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern short ffi_servicepoint_binding_uniffi_rust_future_complete_i16(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_u32(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_u32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_u32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern uint ffi_servicepoint_binding_uniffi_rust_future_complete_u32(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_i32(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_i32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_i32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern int ffi_servicepoint_binding_uniffi_rust_future_complete_i32(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_u64(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_u64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_u64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong ffi_servicepoint_binding_uniffi_rust_future_complete_u64(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_i64(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_i64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_i64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern long ffi_servicepoint_binding_uniffi_rust_future_complete_i64(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_f32(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_f32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_f32(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern float ffi_servicepoint_binding_uniffi_rust_future_complete_f32(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_f64(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_f64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_f64(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern double ffi_servicepoint_binding_uniffi_rust_future_complete_f64(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_pointer(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_pointer(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_pointer(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern SafeHandle ffi_servicepoint_binding_uniffi_rust_future_complete_pointer(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_rust_buffer(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_rust_buffer(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_rust_buffer(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer ffi_servicepoint_binding_uniffi_rust_future_complete_rust_buffer(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_poll_void(IntPtr @handle,IntPtr @uniffiCallback + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_cancel_void(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_free_void(IntPtr @handle + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern uint ffi_servicepoint_binding_uniffi_uniffi_contract_version( + ); + + + + static void uniffiCheckContractApiVersion() { + var scaffolding_contract_version = _UniFFILib.ffi_servicepoint_binding_uniffi_uniffi_contract_version(); + if (24 != scaffolding_contract_version) { + throw new UniffiContractVersionException($"ServicePoint: uniffi bindings expected version `24`, library returned `{scaffolding_contract_version}`"); + } + } + + static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new(); + if (checksum != 31583) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new` checksum `31583`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new(); + if (checksum != 63821) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new` checksum `63821`, library returned `{checksum}`"); + } + } + } +} + +// Public interface members begin here. + +#pragma warning disable 8625 + + + + +class FfiConverterString: FfiConverter { + public static FfiConverterString INSTANCE = new FfiConverterString(); + + // Note: we don't inherit from FfiConverterRustBuffer, because we use a + // special encoding when lowering/lifting. We can use `RustBuffer.len` to + // store our length and avoid writing it out to the buffer. + public override string Lift(RustBuffer value) { + try { + var bytes = value.AsStream().ReadBytes(value.len); + return System.Text.Encoding.UTF8.GetString(bytes); + } finally { + RustBuffer.Free(value); + } + } + + public override string Read(BigEndianStream stream) { + var length = stream.ReadInt(); + var bytes = stream.ReadBytes(length); + return System.Text.Encoding.UTF8.GetString(bytes); + } + + public override RustBuffer Lower(string value) { + var bytes = System.Text.Encoding.UTF8.GetBytes(value); + var rbuf = RustBuffer.Alloc(bytes.Length); + rbuf.AsWriteableStream().WriteBytes(bytes); + return rbuf; + } + + // TODO(CS) + // We aren't sure exactly how many bytes our string will be once it's UTF-8 + // encoded. Allocate 3 bytes per unicode codepoint which will always be + // enough. + public override int AllocationSize(string value) { + const int sizeForLength = 4; + var sizeForString = value.Length * 3; + return sizeForLength + sizeForString; + } + + public override void Write(string value, BigEndianStream stream) { + var bytes = System.Text.Encoding.UTF8.GetBytes(value); + stream.WriteInt(bytes.Length); + stream.WriteBytes(bytes); + } +} + + + + +// `SafeHandle` implements the semantics outlined below, i.e. its thread safe, and the dispose +// method will only be called once, once all outstanding native calls have completed. +// https://github.com/mozilla/uniffi-rs/blob/0dc031132d9493ca812c3af6e7dd60ad2ea95bf0/uniffi_bindgen/src/bindings/kotlin/templates/ObjectRuntime.kt#L31 +// https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.criticalhandle + +public abstract class FFIObject: IDisposable where THandle : FFISafeHandle { + private THandle handle; + + public FFIObject(THandle handle) { + this.handle = handle; + } + + public THandle GetHandle() { + return handle; + } + + public void Dispose() { + handle.Dispose(); + } +} + +public abstract class FFISafeHandle: SafeHandle { + public FFISafeHandle(): base(new IntPtr(0), true) { + } + + public FFISafeHandle(IntPtr pointer): this() { + this.SetHandle(pointer); + } + + public override bool IsInvalid { + get { + return handle.ToInt64() == 0; + } + } + + // TODO(CS) this completely breaks any guarantees offered by SafeHandle.. Extracting + // raw value from SafeHandle puts responsiblity on the consumer of this function to + // ensure that SafeHandle outlives the stream, and anyone who might have read the raw + // value from the stream and are holding onto it. Otherwise, the result might be a use + // after free, or free while method calls are still in flight. + // + // This is also relevant for Kotlin. + // + public IntPtr DangerousGetRawFfiValue() { + return handle; + } +} + +static class FFIObjectUtil { + public static void DisposeAll(params Object?[] list) { + foreach (var obj in list) { + Dispose(obj); + } + } + + // Dispose is implemented by recursive type inspection at runtime. This is because + // generating correct Dispose calls for recursive complex types, e.g. List> + // is quite cumbersome. + private static void Dispose(dynamic? obj) { + if (obj == null) { + return; + } + + if (obj is IDisposable disposable) { + disposable.Dispose(); + return; + } + + var type = obj.GetType(); + if (type != null) { + if (type.IsGenericType) { + if (type.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>))) { + foreach (var value in obj) { + Dispose(value); + } + } else if (type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>))) { + foreach (var value in obj.Values) { + Dispose(value); + } + } + } + } + } +} +public interface IClear { + +} + +public class ClearSafeHandle: FFISafeHandle { + public ClearSafeHandle(): base() { + } + public ClearSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_clear(this.handle, ref status); + }); + return true; + } +} +public class Clear: FFIObject, IClear { + public Clear(ClearSafeHandle pointer): base(pointer) {} + public Clear() : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_clear_new( ref _status) +)) {} + + + + +} + +class FfiConverterTypeClear: FfiConverter { + public static FfiConverterTypeClear INSTANCE = new FfiConverterTypeClear(); + + public override ClearSafeHandle Lower(Clear value) { + return value.GetHandle(); + } + + public override Clear Lift(ClearSafeHandle value) { + return new Clear(value); + } + + public override Clear Read(BigEndianStream stream) { + return Lift(new ClearSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(Clear value) { + return 8; + } + + public override void Write(Clear value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + +public interface ICommand { + +} + +public class CommandSafeHandle: FFISafeHandle { + public CommandSafeHandle(): base() { + } + public CommandSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_command(this.handle, ref status); + }); + return true; + } +} +public class Command: FFIObject, ICommand { + public Command(CommandSafeHandle pointer): base(pointer) {} + + + + +} + +class FfiConverterTypeCommand: FfiConverter { + public static FfiConverterTypeCommand INSTANCE = new FfiConverterTypeCommand(); + + public override CommandSafeHandle Lower(Command value) { + return value.GetHandle(); + } + + public override Command Lift(CommandSafeHandle value) { + return new Command(value); + } + + public override Command Read(BigEndianStream stream) { + return Lift(new CommandSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(Command value) { + return 8; + } + + public override void Write(Command value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + +public interface IConnection { + +} + +public class ConnectionSafeHandle: FFISafeHandle { + public ConnectionSafeHandle(): base() { + } + public ConnectionSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_connection(this.handle, ref status); + }); + return true; + } +} +public class Connection: FFIObject, IConnection { + public Connection(ConnectionSafeHandle pointer): base(pointer) {} + public Connection(String @host) : + this( + _UniffiHelpers.RustCallWithError(FfiConverterTypeConnectionException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new(FfiConverterString.INSTANCE.Lower(@host), ref _status) +)) {} + + + + +} + +class FfiConverterTypeConnection: FfiConverter { + public static FfiConverterTypeConnection INSTANCE = new FfiConverterTypeConnection(); + + public override ConnectionSafeHandle Lower(Connection value) { + return value.GetHandle(); + } + + public override Connection Lift(ConnectionSafeHandle value) { + return new Connection(value); + } + + public override Connection Read(BigEndianStream stream) { + return Lift(new ConnectionSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(Connection value) { + return 8; + } + + public override void Write(Connection value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + + + +public class ConnectionException: UniffiException { + // Each variant is a nested class + + + public class IoException : ConnectionException { + // Members + public String @error; + + // Constructor + public IoException( + String @error) { + this.@error = @error; + } + } + + + +} + +class FfiConverterTypeConnectionException : FfiConverterRustBuffer, CallStatusErrorHandler { + public static FfiConverterTypeConnectionException INSTANCE = new FfiConverterTypeConnectionException(); + + public override ConnectionException Read(BigEndianStream stream) { + var value = stream.ReadInt(); + switch (value) { + case 1: + return new ConnectionException.IoException( + FfiConverterString.INSTANCE.Read(stream)); + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.Read()", value)); + } + } + + public override int AllocationSize(ConnectionException value) { + switch (value) { + case ConnectionException.IoException variant_value: + return 4 + + FfiConverterString.INSTANCE.AllocationSize(variant_value.@error); + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.AllocationSize()", value)); + } + } + + public override void Write(ConnectionException value, BigEndianStream stream) { + switch (value) { + case ConnectionException.IoException variant_value: + stream.WriteInt(1); + FfiConverterString.INSTANCE.Write(variant_value.@error, stream); + break; + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.Write()", value)); + } + } +} +#pragma warning restore 8625 +public static class ServicepointBindingUniffiMethods { +} + diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/csharp.sln b/crates/servicepoint_binding_uniffi/libraries/csharp/csharp.sln new file mode 100644 index 0000000..2fbf818 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/csharp.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "ServicePoint\ServicePoint.csproj", "{53576D3C-E32E-49BF-BF10-2DB504E50CE1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint.Example", "ServicePoint.Example\ServicePoint.Example.csproj", "{FEF24227-090E-46C2-B8F6-ACB5AA1A4309}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint.Tests", "ServicePoint.Tests\ServicePoint.Tests.csproj", "{9DC15508-A980-4135-9FC6-659FF54B4E5C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {53576D3C-E32E-49BF-BF10-2DB504E50CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53576D3C-E32E-49BF-BF10-2DB504E50CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53576D3C-E32E-49BF-BF10-2DB504E50CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53576D3C-E32E-49BF-BF10-2DB504E50CE1}.Release|Any CPU.Build.0 = Release|Any CPU + {FEF24227-090E-46C2-B8F6-ACB5AA1A4309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FEF24227-090E-46C2-B8F6-ACB5AA1A4309}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FEF24227-090E-46C2-B8F6-ACB5AA1A4309}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FEF24227-090E-46C2-B8F6-ACB5AA1A4309}.Release|Any CPU.Build.0 = Release|Any CPU + {9DC15508-A980-4135-9FC6-659FF54B4E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DC15508-A980-4135-9FC6-659FF54B4E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DC15508-A980-4135-9FC6-659FF54B4E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DC15508-A980-4135-9FC6-659FF54B4E5C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-cs.rs b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-cs.rs new file mode 100644 index 0000000..ef11e75 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-cs.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi_bindgen_cs::main().unwrap(); +} diff --git a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs new file mode 100644 index 0000000..f6cff6c --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi::uniffi_bindgen_main() +} diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs new file mode 100644 index 0000000..7d7906c --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -0,0 +1,20 @@ +use std::sync::Arc; + +#[uniffi::export] +trait Command: Send + Sync {} + +#[derive(uniffi::Object)] +pub struct Clear { + actual: servicepoint::Command, +} +#[uniffi::export] +impl Command for Clear {} + +#[uniffi::export] +impl Clear { + #[uniffi::constructor] + pub fn new() -> Arc { + let actual = servicepoint::Command::Clear; + Arc::new(Clear { actual }) + } +} diff --git a/crates/servicepoint_binding_uniffi/src/connection.rs b/crates/servicepoint_binding_uniffi/src/connection.rs new file mode 100644 index 0000000..340e2fe --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/connection.rs @@ -0,0 +1,23 @@ +use std::{sync::Arc}; + +#[derive(uniffi::Object)] +pub struct Connection { + actual: servicepoint::Connection, +} + +#[derive(uniffi::Error, thiserror::Error, Debug)] +pub enum ConnectionError { + #[error("An IO error occured: {error}")] + IOError { + error: String} +} + +#[uniffi::export] +impl Connection { + #[uniffi::constructor] + pub fn new(host: String) -> Result, ConnectionError> { + servicepoint::Connection::open(host) + .map(|actual|Arc::new(Connection { actual}) ) + .map_err(|err| ConnectionError::IOError { error: err.to_string()}) + } +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs new file mode 100644 index 0000000..b87a67a --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -0,0 +1,4 @@ +uniffi::setup_scaffolding!(); + +mod command; +mod connection; diff --git a/crates/servicepoint_binding_uniffi/uniffi.toml b/crates/servicepoint_binding_uniffi/uniffi.toml new file mode 100644 index 0000000..249e237 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/uniffi.toml @@ -0,0 +1,3 @@ +[bindings.csharp] +namespace = "ServicePoint" +access_modifier = "public" From 0dc13949356e3780bea8b6fc56c5323837939cbe Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 3 Nov 2024 11:12:40 +0100 Subject: [PATCH 03/18] send command with connection --- .../generate-bindings.sh | 3 +- .../csharp/ServicePoint.Example/Program.cs | 6 +- .../csharp/ServicePoint.Tests/CommandTests.cs | 36 +++ .../ServicePoint.Tests/ConnectionTests.cs | 11 + .../csharp/ServicePoint.Tests/GlobalUsings.cs | 2 + .../csharp/ServicePoint.Tests/UnitTest1.cs | 12 - .../servicepoint_binding_uniffi.cs | 275 ++++++++++++------ .../src/command.rs | 39 ++- .../src/connection.rs | 28 +- .../servicepoint_binding_uniffi/src/errors.rs | 8 + crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 11 files changed, 299 insertions(+), 122 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ConnectionTests.cs create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/GlobalUsings.cs delete mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs create mode 100644 crates/servicepoint_binding_uniffi/src/errors.rs diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh index 97ad72e..539b61e 100755 --- a/crates/servicepoint_binding_uniffi/generate-bindings.sh +++ b/crates/servicepoint_binding_uniffi/generate-bindings.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -set +x +set -x +set -e cargo build --release diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs index edca01c..ad4a868 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs @@ -1,5 +1,5 @@ using ServicePoint; -var connection = new Connection(""); - -var clear = new Clear(); +var connection = new Connection("127.0.0.1:2342"); +var clear = Command.Clear(); +connection.Send(clear); diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs new file mode 100644 index 0000000..31cb52b --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs @@ -0,0 +1,36 @@ +namespace ServicePoint.Tests; + +public class CommandTests +{ + private Connection _connection = Connection.NewFake(); + + [Fact] + public void ClearSendable() + { + _connection.Send(Command.Clear()); + } + + [Fact] + public void BrightnessSendable() + { + _connection.Send(Command.Brightness(5)); + } + + [Fact] + public void InvalidBrightnessThrows() + { + Assert.Throws(() => Command.Brightness(42)); + } + + [Fact] + public void FadeOutSendable() + { + _connection.Send(Command.FadeOut()); + } + + [Fact] + public void HardResetSendable() + { + _connection.Send(Command.HardReset()); + } +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ConnectionTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ConnectionTests.cs new file mode 100644 index 0000000..be0000f --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/ConnectionTests.cs @@ -0,0 +1,11 @@ +namespace ServicePoint.Tests; + +public class ConnectionTests +{ + [Fact] + public void InvalidHostnameThrows() + { + Assert.Throws(() => new Connection("")); + Assert.Throws(() => new Connection("-%6$§")); + } +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/GlobalUsings.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/GlobalUsings.cs new file mode 100644 index 0000000..a09810b --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Xunit; +global using ServicePoint; diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs deleted file mode 100644 index 46991d7..0000000 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/UnitTest1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ServicePoint; - -namespace ServicePoint.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - Assert.Throws(() => new Connection("")); - } -} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index 5e90f6c..6285122 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -428,20 +428,27 @@ static class _UniFFILib { } - [DllImport("servicepoint_binding_uniffi")] - public static extern void uniffi_servicepoint_binding_uniffi_fn_free_clear( - IntPtr ptr,ref RustCallStatus _uniffi_out_err - ); - - [DllImport("servicepoint_binding_uniffi")] - public static extern ClearSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_clear_new(ref RustCallStatus _uniffi_out_err - ); - [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_command( IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(byte @brightness,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear(ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out(ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset(ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_connection( IntPtr ptr,ref RustCallStatus _uniffi_out_err @@ -451,6 +458,14 @@ static class _UniFFILib { public static extern ConnectionSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new(RustBuffer @host,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ConnectionSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake(ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_connection_send(ConnectionSafeHandle @ptr,CommandSafeHandle @command,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_alloc(int @size,ref RustCallStatus _uniffi_out_err ); @@ -680,13 +695,33 @@ static class _UniFFILib { ); [DllImport("servicepoint_binding_uniffi")] - public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new( + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_hard_reset( ); [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern uint ffi_servicepoint_binding_uniffi_uniffi_contract_version( ); @@ -702,15 +737,45 @@ static class _UniFFILib { static void uniffiCheckApiChecksums() { { - var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new(); - if (checksum != 31583) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_clear_new` checksum `31583`, library returned `{checksum}`"); + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_connection_send(); + if (checksum != 23796) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness(); + if (checksum != 11291) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness` checksum `11291`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear(); + if (checksum != 11035) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear` checksum `11035`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out(); + if (checksum != 49231) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out` checksum `49231`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_hard_reset(); + if (checksum != 62130) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_hard_reset` checksum `62130`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new(); - if (checksum != 63821) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new` checksum `63821`, library returned `{checksum}`"); + if (checksum != 30445) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new` checksum `30445`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake(); + if (checksum != 54331) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake` checksum `54331`, library returned `{checksum}`"); } } } @@ -723,6 +788,32 @@ static class _UniFFILib { +class FfiConverterUInt8: FfiConverter { + public static FfiConverterUInt8 INSTANCE = new FfiConverterUInt8(); + + public override byte Lift(byte value) { + return value; + } + + public override byte Read(BigEndianStream stream) { + return stream.ReadByte(); + } + + public override byte Lower(byte value) { + return value; + } + + public override int AllocationSize(byte value) { + return 1; + } + + public override void Write(byte value, BigEndianStream stream) { + stream.WriteByte(value); + } +} + + + class FfiConverterString: FfiConverter { public static FfiConverterString INSTANCE = new FfiConverterString(); @@ -855,61 +946,6 @@ static class FFIObjectUtil { } } } -public interface IClear { - -} - -public class ClearSafeHandle: FFISafeHandle { - public ClearSafeHandle(): base() { - } - public ClearSafeHandle(IntPtr pointer): base(pointer) { - } - override protected bool ReleaseHandle() { - _UniffiHelpers.RustCall((ref RustCallStatus status) => { - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_clear(this.handle, ref status); - }); - return true; - } -} -public class Clear: FFIObject, IClear { - public Clear(ClearSafeHandle pointer): base(pointer) {} - public Clear() : - this( - _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_clear_new( ref _status) -)) {} - - - - -} - -class FfiConverterTypeClear: FfiConverter { - public static FfiConverterTypeClear INSTANCE = new FfiConverterTypeClear(); - - public override ClearSafeHandle Lower(Clear value) { - return value.GetHandle(); - } - - public override Clear Lift(ClearSafeHandle value) { - return new Clear(value); - } - - public override Clear Read(BigEndianStream stream) { - return Lift(new ClearSafeHandle(new IntPtr(stream.ReadLong()))); - } - - public override int AllocationSize(Clear value) { - return 8; - } - - public override void Write(Clear value, BigEndianStream stream) { - stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); - } -} - - - public interface ICommand { } @@ -932,6 +968,36 @@ public class Command: FFIObject, ICommand { + /// + public static Command Brightness(byte @brightness) { + return new Command( + _UniffiHelpers.RustCallWithError(FfiConverterTypeServicePointException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(FfiConverterUInt8.INSTANCE.Lower(@brightness), ref _status) +)); + } + + public static Command Clear() { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear( ref _status) +)); + } + + public static Command FadeOut() { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out( ref _status) +)); + } + + public static Command HardReset() { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset( ref _status) +)); + } + + } class FfiConverterTypeCommand: FfiConverter { @@ -962,6 +1028,9 @@ class FfiConverterTypeCommand: FfiConverter { public interface IConnection { + /// + void Send(Command @command); + } public class ConnectionSafeHandle: FFISafeHandle { @@ -980,13 +1049,29 @@ public class Connection: FFIObject, IConnection { public Connection(ConnectionSafeHandle pointer): base(pointer) {} public Connection(String @host) : this( - _UniffiHelpers.RustCallWithError(FfiConverterTypeConnectionException.INSTANCE, (ref RustCallStatus _status) => + _UniffiHelpers.RustCallWithError(FfiConverterTypeServicePointException.INSTANCE, (ref RustCallStatus _status) => _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new(FfiConverterString.INSTANCE.Lower(@host), ref _status) )) {} + /// + public void Send(Command @command) { + _UniffiHelpers.RustCallWithError(FfiConverterTypeServicePointException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_connection_send(this.GetHandle(), FfiConverterTypeCommand.INSTANCE.Lower(@command), ref _status) +); + } + + + public static Connection NewFake() { + return new Connection( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake( ref _status) +)); + } + + } class FfiConverterTypeConnection: FfiConverter { @@ -1017,11 +1102,11 @@ class FfiConverterTypeConnection: FfiConverter -public class ConnectionException: UniffiException { +public class ServicePointException: UniffiException { // Each variant is a nested class - public class IoException : ConnectionException { + public class IoException : ServicePointException { // Members public String @error; @@ -1032,42 +1117,64 @@ public class ConnectionException: UniffiException { } } + + public class InvalidBrightness : ServicePointException { + // Members + public byte @value; + + // Constructor + public InvalidBrightness( + byte @value) { + this.@value = @value; + } + } + } -class FfiConverterTypeConnectionException : FfiConverterRustBuffer, CallStatusErrorHandler { - public static FfiConverterTypeConnectionException INSTANCE = new FfiConverterTypeConnectionException(); +class FfiConverterTypeServicePointException : FfiConverterRustBuffer, CallStatusErrorHandler { + public static FfiConverterTypeServicePointException INSTANCE = new FfiConverterTypeServicePointException(); - public override ConnectionException Read(BigEndianStream stream) { + public override ServicePointException Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: - return new ConnectionException.IoException( + return new ServicePointException.IoException( FfiConverterString.INSTANCE.Read(stream)); + case 2: + return new ServicePointException.InvalidBrightness( + FfiConverterUInt8.INSTANCE.Read(stream)); default: - throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.Read()", value)); + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeServicePointException.Read()", value)); } } - public override int AllocationSize(ConnectionException value) { + public override int AllocationSize(ServicePointException value) { switch (value) { - case ConnectionException.IoException variant_value: + case ServicePointException.IoException variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@error); + case ServicePointException.InvalidBrightness variant_value: + return 4 + + FfiConverterUInt8.INSTANCE.AllocationSize(variant_value.@value); default: - throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.AllocationSize()", value)); + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeServicePointException.AllocationSize()", value)); } } - public override void Write(ConnectionException value, BigEndianStream stream) { + public override void Write(ServicePointException value, BigEndianStream stream) { switch (value) { - case ConnectionException.IoException variant_value: + case ServicePointException.IoException variant_value: stream.WriteInt(1); FfiConverterString.INSTANCE.Write(variant_value.@error, stream); break; + case ServicePointException.InvalidBrightness variant_value: + stream.WriteInt(2); + FfiConverterUInt8.INSTANCE.Write(variant_value.@value, stream); + break; default: - throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeConnectionException.Write()", value)); + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeServicePointException.Write()", value)); } } } diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index 7d7906c..81562a7 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,20 +1,37 @@ use std::sync::Arc; - -#[uniffi::export] -trait Command: Send + Sync {} +use crate::errors::ServicePointError; #[derive(uniffi::Object)] -pub struct Clear { - actual: servicepoint::Command, +pub struct Command { + pub(crate)actual: servicepoint::Command +} + +fn actual_into_arc(actual: servicepoint::Command) -> Arc { + Arc::new(Command { actual }) } -#[uniffi::export] -impl Command for Clear {} #[uniffi::export] -impl Clear { +impl Command { #[uniffi::constructor] - pub fn new() -> Arc { - let actual = servicepoint::Command::Clear; - Arc::new(Clear { actual }) + pub fn clear() -> Arc { + actual_into_arc(servicepoint::Command::Clear) + } + + #[uniffi::constructor] + pub fn brightness(brightness: u8) -> Result, ServicePointError> { + servicepoint::Brightness::try_from(brightness) + .map_err(move |value| ServicePointError::InvalidBrightness{value}) + .map(servicepoint::Command::Brightness) + .map(actual_into_arc) + } + + #[uniffi::constructor] + pub fn fade_out() -> Arc { + actual_into_arc(servicepoint::Command::FadeOut) + } + + #[uniffi::constructor] + pub fn hard_reset() -> Arc { + actual_into_arc(servicepoint::Command::HardReset) } } diff --git a/crates/servicepoint_binding_uniffi/src/connection.rs b/crates/servicepoint_binding_uniffi/src/connection.rs index 340e2fe..4e7ed79 100644 --- a/crates/servicepoint_binding_uniffi/src/connection.rs +++ b/crates/servicepoint_binding_uniffi/src/connection.rs @@ -1,23 +1,29 @@ -use std::{sync::Arc}; +use std::sync::Arc; + +use crate::command::Command; +use crate::errors::ServicePointError; #[derive(uniffi::Object)] pub struct Connection { actual: servicepoint::Connection, } -#[derive(uniffi::Error, thiserror::Error, Debug)] -pub enum ConnectionError { - #[error("An IO error occured: {error}")] - IOError { - error: String} -} - #[uniffi::export] impl Connection { #[uniffi::constructor] - pub fn new(host: String) -> Result, ConnectionError> { + pub fn new(host: String) -> Result, ServicePointError> { servicepoint::Connection::open(host) - .map(|actual|Arc::new(Connection { actual}) ) - .map_err(|err| ConnectionError::IOError { error: err.to_string()}) + .map(|actual| Arc::new(Connection { actual })) + .map_err(|err| ServicePointError::IOError { error: err.to_string() }) + } + + #[uniffi::constructor] + pub fn new_fake() -> Arc { + Arc::new(Self { actual: servicepoint::Connection::Fake }) + } + + pub fn send(&self, command: Arc) -> Result<(), ServicePointError> { + self.actual.send(command.actual.clone()) + .map_err(|err| ServicePointError::IOError { error: format!("{err:?}") }) } } diff --git a/crates/servicepoint_binding_uniffi/src/errors.rs b/crates/servicepoint_binding_uniffi/src/errors.rs new file mode 100644 index 0000000..bb41d81 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/errors.rs @@ -0,0 +1,8 @@ + +#[derive(uniffi::Error, thiserror::Error, Debug)] +pub enum ServicePointError { + #[error("An IO error occurred: {error}")] + IOError {error: String}, + #[error("The specified brightness value {value} is out of range")] + InvalidBrightness {value:u8}, +} \ No newline at end of file diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index b87a67a..b86bdaa 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -2,3 +2,4 @@ uniffi::setup_scaffolding!(); mod command; mod connection; +mod errors; From 6e467502f2df7b36cb6797f5e8206e56ada8add8 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 3 Nov 2024 11:42:37 +0100 Subject: [PATCH 04/18] add go and ruby add ruby --- crates/servicepoint_binding_uniffi/Cargo.toml | 21 ++++++++++++++----- .../generate-bindings.sh | 3 +++ .../src/bin/uniffi-bindgen-go.rs | 3 +++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml index 5ba77a5..58248c3 100644 --- a/crates/servicepoint_binding_uniffi/Cargo.toml +++ b/crates/servicepoint_binding_uniffi/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/cccb/servicepoint" crate-type = ["cdylib"] [build-dependencies] -uniffi = { version = "0.25.0" , features = [ "build" ] } +uniffi = { version = "0.25.0", features = ["build"] } [dependencies] uniffi = { version = "0.25.0" } @@ -25,10 +25,16 @@ path = "../servicepoint" features = ["all_compressions"] [dependencies.uniffi-bindgen-cs] -git="https://github.com/NordSecurity/uniffi-bindgen-cs" +git = "https://github.com/NordSecurity/uniffi-bindgen-cs" # tag="v0.8.3+v0.25.0" -rev="f68639fbc720b50ebe561ba75c66c84dc456bdce" -optional=true +rev = "f68639fbc720b50ebe561ba75c66c84dc456bdce" +optional = true + +[dependencies.uniffi-bindgen-go] +git = "https://github.com/NordSecurity/uniffi-bindgen-go.git" +# tag = "0.2.1+v0.25.0" +rev = "a77dc0462dc18d53846c758155ab4e0a42e5b240" +optional = true [lints] #workspace = true @@ -42,8 +48,13 @@ required-features = ["uniffi/cli"] [[bin]] name = "uniffi-bindgen-cs" -required-features= ["cs"] +required-features = ["cs"] + +[[bin]] +name = "uniffi-bindgen-go" +required-features = ["go"] [features] default = [] cs = ["dep:uniffi-bindgen-cs"] +go = ["dep:uniffi-bindgen-go"] \ No newline at end of file diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh index 539b61e..a25a809 100755 --- a/crates/servicepoint_binding_uniffi/generate-bindings.sh +++ b/crates/servicepoint_binding_uniffi/generate-bindings.sh @@ -12,9 +12,12 @@ CONFIG_TOML="$(realpath $SCRIPTPATH/../uniffi.toml)" BINDGEN="cargo run --features=uniffi/cli --bin uniffi-bindgen -- " BINDGEN_CS="cargo run --features=cs --bin uniffi-bindgen-cs -- " +BINDGEN_GO="cargo run --features=go --bin uniffi-bindgen-go -- " COMMON_ARGS="--library $SERVICEPOINT_SO" ${BINDGEN} generate $COMMON_ARGS --language python --out-dir libraries/python ${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir libraries/kotlin ${BINDGEN} generate $COMMON_ARGS --language swift --out-dir libraries/swift +${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir libraries/ruby ${BINDGEN_CS} $COMMON_ARGS --out-dir libraries/csharp/ServicePoint +${BINDGEN_GO} $COMMON_ARGS --out-dir libraries/go/ diff --git a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs new file mode 100644 index 0000000..5f01856 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi_bindgen_go::main().unwrap(); +} From f9c8d20654089cb578414f151626de629e6534f1 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 19:20:40 +0100 Subject: [PATCH 05/18] add bitmap for uniffi, BitmapLinearWin add uniffi BitmapLinearWin command --- .../generate-bindings.sh | 25 +- .../csharp/ServicePoint.Tests/BitmapTests.cs | 16 + .../csharp/ServicePoint.Tests/CommandTests.cs | 6 + .../servicepoint_binding_uniffi.cs | 284 ++++++++++++++++++ .../servicepoint_binding_uniffi/src/bitmap.rs | 45 +++ .../src/command.rs | 25 +- .../src/connection.rs | 4 +- .../servicepoint_binding_uniffi/src/errors.rs | 2 +- crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 9 files changed, 387 insertions(+), 21 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/BitmapTests.cs create mode 100644 crates/servicepoint_binding_uniffi/src/bitmap.rs diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh index a25a809..5b0866d 100755 --- a/crates/servicepoint_binding_uniffi/generate-bindings.sh +++ b/crates/servicepoint_binding_uniffi/generate-bindings.sh @@ -1,23 +1,24 @@ #!/usr/bin/env bash - -set -x set -e cargo build --release -SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -TARGETPATH="$(realpath $SCRIPTPATH/../../target/release/)" -SERVICEPOINT_SO="$TARGETPATH/libservicepoint_binding_uniffi.so" -CONFIG_TOML="$(realpath $SCRIPTPATH/../uniffi.toml)" +SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +TARGET_PATH="$(realpath "$SCRIPT_PATH"/../../target/release)" +SERVICEPOINT_SO="$TARGET_PATH/libservicepoint_binding_uniffi.so" +LIBRARIES_PATH="$SCRIPT_PATH/libraries" + +echo "Source: $SERVICEPOINT_SO" +echo "Output: $LIBRARIES_PATH" BINDGEN="cargo run --features=uniffi/cli --bin uniffi-bindgen -- " BINDGEN_CS="cargo run --features=cs --bin uniffi-bindgen-cs -- " BINDGEN_GO="cargo run --features=go --bin uniffi-bindgen-go -- " COMMON_ARGS="--library $SERVICEPOINT_SO" -${BINDGEN} generate $COMMON_ARGS --language python --out-dir libraries/python -${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir libraries/kotlin -${BINDGEN} generate $COMMON_ARGS --language swift --out-dir libraries/swift -${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir libraries/ruby -${BINDGEN_CS} $COMMON_ARGS --out-dir libraries/csharp/ServicePoint -${BINDGEN_GO} $COMMON_ARGS --out-dir libraries/go/ +${BINDGEN} generate $COMMON_ARGS --language python --out-dir "$LIBRARIES_PATH/python" +${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir "$LIBRARIES_PATH/kotlin" +${BINDGEN} generate $COMMON_ARGS --language swift --out-dir "$LIBRARIES_PATH/swift" +${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir "$LIBRARIES_PATH/ruby" +${BINDGEN_CS} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/csharp/ServicePoint" +${BINDGEN_GO} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/go/" diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/BitmapTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/BitmapTests.cs new file mode 100644 index 0000000..9e55a80 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/BitmapTests.cs @@ -0,0 +1,16 @@ +namespace ServicePoint.Tests; + +public class BitmapTests +{ + [Fact] + public void BasicFunctions() + { + var bitmap = new Bitmap(8, 2); + Assert.False(bitmap.Get(0, 0)); + Assert.False(bitmap.Get(bitmap.Width() - 1, bitmap.Height() - 1)); + bitmap.Fill(true); + Assert.True(bitmap.Get(1, 1)); + bitmap.Set(1, 1, false); + Assert.False(bitmap.Get(1, 1)); + } +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs index 31cb52b..b17deb3 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs @@ -33,4 +33,10 @@ public class CommandTests { _connection.Send(Command.HardReset()); } + + [Fact] + public void BitmapLinearWinSendable() + { + _connection.Send(Command.BitmapLinearWin(0, 0, Bitmap.NewMaxSized())); + } } diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index 6285122..b72b1b1 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -428,11 +428,48 @@ static class _UniFFILib { } + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_bitmap( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized(ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill(BitmapSafeHandle @ptr,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get(BitmapSafeHandle @ptr,ulong @x,ulong @y,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height(BitmapSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set(BitmapSafeHandle @ptr,ulong @x,ulong @y,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width(BitmapSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_command( IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(ulong @offsetX,ulong @offsetY,BitmapSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(byte @brightness,ref RustCallStatus _uniffi_out_err ); @@ -694,10 +731,42 @@ static class _UniFFILib { public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_height( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_set( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness( ); @@ -736,12 +805,60 @@ static class _UniFFILib { } static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill(); + if (checksum != 43887) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill` checksum `43887`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_get(); + if (checksum != 61136) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_get` checksum `61136`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_height(); + if (checksum != 44991) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_height` checksum `44991`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_set(); + if (checksum != 25290) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_set` checksum `25290`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width(); + if (checksum != 30837) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width` checksum `30837`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_connection_send(); if (checksum != 23796) { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new(); + if (checksum != 49832) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new` checksum `49832`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized(); + if (checksum != 63762) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized` checksum `63762`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win(); + if (checksum != 51700) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win` checksum `51700`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness(); if (checksum != 11291) { @@ -814,6 +931,58 @@ class FfiConverterUInt8: FfiConverter { +class FfiConverterUInt64: FfiConverter { + public static FfiConverterUInt64 INSTANCE = new FfiConverterUInt64(); + + public override ulong Lift(ulong value) { + return value; + } + + public override ulong Read(BigEndianStream stream) { + return stream.ReadULong(); + } + + public override ulong Lower(ulong value) { + return value; + } + + public override int AllocationSize(ulong value) { + return 8; + } + + public override void Write(ulong value, BigEndianStream stream) { + stream.WriteULong(value); + } +} + + + +class FfiConverterBoolean: FfiConverter { + public static FfiConverterBoolean INSTANCE = new FfiConverterBoolean(); + + public override bool Lift(sbyte value) { + return value != 0; + } + + public override bool Read(BigEndianStream stream) { + return Lift(stream.ReadSByte()); + } + + public override sbyte Lower(bool value) { + return value ? (sbyte)1 : (sbyte)0; + } + + public override int AllocationSize(bool value) { + return (sbyte)1; + } + + public override void Write(bool value, BigEndianStream stream) { + stream.WriteSByte(Lower(value)); + } +} + + + class FfiConverterString: FfiConverter { public static FfiConverterString INSTANCE = new FfiConverterString(); @@ -946,6 +1115,114 @@ static class FFIObjectUtil { } } } +public interface IBitmap { + + void Fill(bool @value); + + bool Get(ulong @x, ulong @y); + + ulong Height(); + + void Set(ulong @x, ulong @y, bool @value); + + ulong Width(); + +} + +public class BitmapSafeHandle: FFISafeHandle { + public BitmapSafeHandle(): base() { + } + public BitmapSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_bitmap(this.handle, ref status); + }); + return true; + } +} +public class Bitmap: FFIObject, IBitmap { + public Bitmap(BitmapSafeHandle pointer): base(pointer) {} + public Bitmap(ulong @width, ulong @height) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), ref _status) +)) {} + + + public void Fill(bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill(this.GetHandle(), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + public bool Get(ulong @x, ulong @y) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), ref _status) +)); + } + + public ulong Height() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height(this.GetHandle(), ref _status) +)); + } + + public void Set(ulong @x, ulong @y, bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + public ulong Width() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width(this.GetHandle(), ref _status) +)); + } + + + + public static Bitmap NewMaxSized() { + return new Bitmap( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized( ref _status) +)); + } + + +} + +class FfiConverterTypeBitmap: FfiConverter { + public static FfiConverterTypeBitmap INSTANCE = new FfiConverterTypeBitmap(); + + public override BitmapSafeHandle Lower(Bitmap value) { + return value.GetHandle(); + } + + public override Bitmap Lift(BitmapSafeHandle value) { + return new Bitmap(value); + } + + public override Bitmap Read(BigEndianStream stream) { + return Lift(new BitmapSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(Bitmap value) { + return 8; + } + + public override void Write(Bitmap value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public interface ICommand { } @@ -968,6 +1245,13 @@ public class Command: FFIObject, ICommand { + public static Command BitmapLinearWin(ulong @offsetX, ulong @offsetY, Bitmap @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(FfiConverterUInt64.INSTANCE.Lower(@offsetX), FfiConverterUInt64.INSTANCE.Lower(@offsetY), FfiConverterTypeBitmap.INSTANCE.Lower(@bitmap), ref _status) +)); + } + /// public static Command Brightness(byte @brightness) { return new Command( diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs new file mode 100644 index 0000000..8e6fc0b --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -0,0 +1,45 @@ +use std::sync::{Arc, RwLock}; +use servicepoint::Grid; + +#[derive(uniffi::Object)] +pub struct Bitmap { + pub(crate) actual: RwLock, +} + +impl Bitmap { + fn internal_new(actual: servicepoint::Bitmap)-> Arc { + Arc::new(Self { actual: RwLock::new(actual) }) + } +} + +#[uniffi::export] +impl Bitmap { + #[uniffi::constructor] + pub fn new(width: u64, height: u64) -> Arc { + Self::internal_new(servicepoint::Bitmap::new(width as usize, height as usize)) + } + + #[uniffi::constructor] + pub fn new_max_sized() -> Arc { + Self::internal_new(servicepoint::Bitmap::max_sized()) + } + + pub fn set(&self, x: u64, y: u64, value: bool) { + self.actual.write().unwrap().set(x as usize, y as usize, value) + } + + pub fn get(&self, x: u64, y: u64) -> bool { + self.actual.read().unwrap().get(x as usize, y as usize) + } + + pub fn fill(&self, value: bool) { + self.actual.write().unwrap().fill(value) + } + pub fn width(&self) -> u64 { + self.actual.read().unwrap().width() as u64 + } + + pub fn height(&self) -> u64 { + self.actual.read().unwrap().height() as u64 + } +} diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index 81562a7..78b6f2f 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,4 +1,6 @@ use std::sync::Arc; +use servicepoint::{CompressionCode, Origin}; +use crate::bitmap::Bitmap; use crate::errors::ServicePointError; #[derive(uniffi::Object)] @@ -6,15 +8,17 @@ pub struct Command { pub(crate)actual: servicepoint::Command } -fn actual_into_arc(actual: servicepoint::Command) -> Arc { - Arc::new(Command { actual }) +impl Command { + fn internal_new(actual: servicepoint::Command)-> Arc { + Arc::new(Command { actual }) + } } #[uniffi::export] impl Command { #[uniffi::constructor] pub fn clear() -> Arc { - actual_into_arc(servicepoint::Command::Clear) + Self::internal_new(servicepoint::Command::Clear) } #[uniffi::constructor] @@ -22,16 +26,25 @@ impl Command { servicepoint::Brightness::try_from(brightness) .map_err(move |value| ServicePointError::InvalidBrightness{value}) .map(servicepoint::Command::Brightness) - .map(actual_into_arc) + .map(Self::internal_new) } #[uniffi::constructor] pub fn fade_out() -> Arc { - actual_into_arc(servicepoint::Command::FadeOut) + Self::internal_new(servicepoint::Command::FadeOut) } #[uniffi::constructor] pub fn hard_reset() -> Arc { - actual_into_arc(servicepoint::Command::HardReset) + Self::internal_new(servicepoint::Command::HardReset) + } + + #[uniffi::constructor] + pub fn bitmap_linear_win(offset_x: u64, offset_y: u64, bitmap: &Arc) -> Arc { + let origin = Origin::new(offset_x as usize, offset_y as usize); + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearWin(origin, bitmap, CompressionCode::Uncompressed); + Self::internal_new(actual) } } diff --git a/crates/servicepoint_binding_uniffi/src/connection.rs b/crates/servicepoint_binding_uniffi/src/connection.rs index 4e7ed79..a578135 100644 --- a/crates/servicepoint_binding_uniffi/src/connection.rs +++ b/crates/servicepoint_binding_uniffi/src/connection.rs @@ -14,7 +14,7 @@ impl Connection { pub fn new(host: String) -> Result, ServicePointError> { servicepoint::Connection::open(host) .map(|actual| Arc::new(Connection { actual })) - .map_err(|err| ServicePointError::IOError { error: err.to_string() }) + .map_err(|err| ServicePointError::IoError { error: err.to_string() }) } #[uniffi::constructor] @@ -24,6 +24,6 @@ impl Connection { pub fn send(&self, command: Arc) -> Result<(), ServicePointError> { self.actual.send(command.actual.clone()) - .map_err(|err| ServicePointError::IOError { error: format!("{err:?}") }) + .map_err(|err| ServicePointError::IoError { error: format!("{err:?}") }) } } diff --git a/crates/servicepoint_binding_uniffi/src/errors.rs b/crates/servicepoint_binding_uniffi/src/errors.rs index bb41d81..e602342 100644 --- a/crates/servicepoint_binding_uniffi/src/errors.rs +++ b/crates/servicepoint_binding_uniffi/src/errors.rs @@ -2,7 +2,7 @@ #[derive(uniffi::Error, thiserror::Error, Debug)] pub enum ServicePointError { #[error("An IO error occurred: {error}")] - IOError {error: String}, + IoError {error: String}, #[error("The specified brightness value {value} is out of range")] InvalidBrightness {value:u8}, } \ No newline at end of file diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index b86bdaa..65f283f 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -3,3 +3,4 @@ uniffi::setup_scaffolding!(); mod command; mod connection; mod errors; +mod bitmap; From 960f12ebc54a7ea3605c3b1c93468669fb5eb77e Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 21:06:01 +0100 Subject: [PATCH 06/18] make BitVec type alias pub, uniffi bitvec original c# example equivalent works add uniffi bitvec original c# example now works with a few tweaks via uniffi --- .../csharp/ServicePoint.Example/Program.cs | 20 +- .../servicepoint_binding_uniffi.cs | 314 ++++++++++++++++++ .../servicepoint_binding_uniffi/src/bitmap.rs | 29 +- .../servicepoint_binding_uniffi/src/bitvec.rs | 46 +++ .../src/command.rs | 74 ++++- .../src/connection.rs | 15 +- .../servicepoint_binding_uniffi/src/errors.rs | 7 +- crates/servicepoint_binding_uniffi/src/lib.rs | 3 +- 8 files changed, 482 insertions(+), 26 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/src/bitvec.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs index ad4a868..48462a5 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs @@ -1,5 +1,19 @@ -using ServicePoint; +using System.Threading; +using ServicePoint; var connection = new Connection("127.0.0.1:2342"); -var clear = Command.Clear(); -connection.Send(clear); +connection.Send(Command.Clear()); + +connection.Send(Command.Brightness(5)); + +var pixels = Bitmap.NewMaxSized(); +for (ulong offset = 0; offset < ulong.MaxValue; offset++) +{ + pixels.Fill(false); + + for (ulong y = 0; y < pixels.Height(); y++) + pixels.Set((y + offset) % pixels.Width(), y, true); + + connection.Send(Command.BitmapLinearWin(0, 0, pixels)); + Thread.Sleep(14); +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index b72b1b1..9aaf721 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -428,11 +428,44 @@ static class _UniFFILib { } + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_bitvec( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load(RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new(ulong @size,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(BitVecSafeHandle @ptr,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get(BitVecSafeHandle @ptr,ulong @index,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len(BitVecSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set(BitVecSafeHandle @ptr,ulong @index,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_bitmap( IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err ); @@ -466,10 +499,26 @@ static class _UniFFILib { IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(ulong @offsetX,ulong @offsetY,BitmapSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(byte @brightness,ref RustCallStatus _uniffi_out_err ); @@ -731,6 +780,22 @@ static class _UniFFILib { public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill( ); @@ -755,6 +820,18 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new( ); @@ -763,10 +840,26 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness( ); @@ -805,6 +898,30 @@ static class _UniFFILib { } static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill(); + if (checksum != 12255) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill` checksum `12255`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get(); + if (checksum != 43835) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get` checksum `43835`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len(); + if (checksum != 22196) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len` checksum `22196`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set(); + if (checksum != 16307) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set` checksum `16307`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill(); if (checksum != 43887) { @@ -841,6 +958,24 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load(); + if (checksum != 48913) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load` checksum `48913`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new(); + if (checksum != 11865) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new` checksum `11865`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load(); + if (checksum != 24109) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load` checksum `24109`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new(); if (checksum != 49832) { @@ -853,12 +988,36 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized` checksum `63762`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear(); + if (checksum != 14881) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear` checksum `14881`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and(); + if (checksum != 7352) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and` checksum `7352`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or(); + if (checksum != 7046) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or` checksum `7046`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win(); if (checksum != 51700) { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win` checksum `51700`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor(); + if (checksum != 54209) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor` checksum `54209`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness(); if (checksum != 11291) { @@ -1031,6 +1190,27 @@ class FfiConverterString: FfiConverter { +class FfiConverterByteArray: FfiConverterRustBuffer { + public static FfiConverterByteArray INSTANCE = new FfiConverterByteArray(); + + public override byte[] Read(BigEndianStream stream) { + var length = stream.ReadInt(); + return stream.ReadBytes(length); + } + + public override int AllocationSize(byte[] value) { + return 4 + value.Length; + } + + public override void Write(byte[] value, BigEndianStream stream) { + stream.WriteInt(value.Length); + stream.WriteBytes(value); + } +} + + + + // `SafeHandle` implements the semantics outlined below, i.e. its thread safe, and the dispose // method will only be called once, once all outstanding native calls have completed. // https://github.com/mozilla/uniffi-rs/blob/0dc031132d9493ca812c3af6e7dd60ad2ea95bf0/uniffi_bindgen/src/bindings/kotlin/templates/ObjectRuntime.kt#L31 @@ -1115,6 +1295,105 @@ static class FFIObjectUtil { } } } +public interface IBitVec { + + void Fill(bool @value); + + bool Get(ulong @index); + + ulong Len(); + + void Set(ulong @index, bool @value); + +} + +public class BitVecSafeHandle: FFISafeHandle { + public BitVecSafeHandle(): base() { + } + public BitVecSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_bitvec(this.handle, ref status); + }); + return true; + } +} +public class BitVec: FFIObject, IBitVec { + public BitVec(BitVecSafeHandle pointer): base(pointer) {} + public BitVec(ulong @size) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new(FfiConverterUInt64.INSTANCE.Lower(@size), ref _status) +)) {} + + + public void Fill(bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(this.GetHandle(), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + public bool Get(ulong @index) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@index), ref _status) +)); + } + + public ulong Len() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len(this.GetHandle(), ref _status) +)); + } + + public void Set(ulong @index, bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@index), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + + + public static BitVec Load(byte[] @data) { + return new BitVec( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load(FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + + +} + +class FfiConverterTypeBitVec: FfiConverter { + public static FfiConverterTypeBitVec INSTANCE = new FfiConverterTypeBitVec(); + + public override BitVecSafeHandle Lower(BitVec value) { + return value.GetHandle(); + } + + public override BitVec Lift(BitVecSafeHandle value) { + return new BitVec(value); + } + + public override BitVec Read(BigEndianStream stream) { + return Lift(new BitVecSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(BitVec value) { + return 8; + } + + public override void Write(BitVec value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public interface IBitmap { void Fill(bool @value); @@ -1187,6 +1466,13 @@ public class Bitmap: FFIObject, IBitmap { + public static Bitmap Load(ulong @width, ulong @height, byte[] @data) { + return new Bitmap( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + public static Bitmap NewMaxSized() { return new Bitmap( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1245,6 +1531,27 @@ public class Command: FFIObject, ICommand { + public static Command BitmapLinear(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + + public static Command BitmapLinearAnd(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + + public static Command BitmapLinearOr(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + public static Command BitmapLinearWin(ulong @offsetX, ulong @offsetY, Bitmap @bitmap) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1252,6 +1559,13 @@ public class Command: FFIObject, ICommand { )); } + public static Command BitmapLinearXor(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + /// public static Command Brightness(byte @brightness) { return new Command( diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs index 8e6fc0b..e0ebea4 100644 --- a/crates/servicepoint_binding_uniffi/src/bitmap.rs +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -1,5 +1,5 @@ -use std::sync::{Arc, RwLock}; use servicepoint::Grid; +use std::sync::{Arc, RwLock}; #[derive(uniffi::Object)] pub struct Bitmap { @@ -7,8 +7,10 @@ pub struct Bitmap { } impl Bitmap { - fn internal_new(actual: servicepoint::Bitmap)-> Arc { - Arc::new(Self { actual: RwLock::new(actual) }) + fn internal_new(actual: servicepoint::Bitmap) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) } } @@ -16,7 +18,10 @@ impl Bitmap { impl Bitmap { #[uniffi::constructor] pub fn new(width: u64, height: u64) -> Arc { - Self::internal_new(servicepoint::Bitmap::new(width as usize, height as usize)) + Self::internal_new(servicepoint::Bitmap::new( + width as usize, + height as usize, + )) } #[uniffi::constructor] @@ -24,8 +29,20 @@ impl Bitmap { Self::internal_new(servicepoint::Bitmap::max_sized()) } + #[uniffi::constructor] + pub fn load(width: u64, height: u64, data: Vec) -> Arc { + Self::internal_new(servicepoint::Bitmap::load( + width as usize, + height as usize, + &data, + )) + } + pub fn set(&self, x: u64, y: u64, value: bool) { - self.actual.write().unwrap().set(x as usize, y as usize, value) + self.actual + .write() + .unwrap() + .set(x as usize, y as usize, value) } pub fn get(&self, x: u64, y: u64) -> bool { @@ -38,7 +55,7 @@ impl Bitmap { pub fn width(&self) -> u64 { self.actual.read().unwrap().width() as u64 } - + pub fn height(&self) -> u64 { self.actual.read().unwrap().height() as u64 } diff --git a/crates/servicepoint_binding_uniffi/src/bitvec.rs b/crates/servicepoint_binding_uniffi/src/bitvec.rs new file mode 100644 index 0000000..f495958 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bitvec.rs @@ -0,0 +1,46 @@ +use std::sync::{Arc, RwLock}; + +#[derive(uniffi::Object)] +pub struct BitVec { + pub(crate) actual: RwLock, +} + +impl BitVec { + fn internal_new(actual: servicepoint::BitVec) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) + } +} + +#[uniffi::export] +impl BitVec { + #[uniffi::constructor] + pub fn new(size: u64) -> Arc { + Self::internal_new(servicepoint::BitVec::repeat(false, size as usize)) + } + #[uniffi::constructor] + pub fn load(data: Vec) -> Arc { + Self::internal_new(servicepoint::BitVec::from_slice(&data)) + } + + pub fn set(&self, index: u64, value: bool) { + self.actual.write().unwrap().set(index as usize, value) + } + + pub fn get(&self, index: u64) -> bool { + self.actual + .read() + .unwrap() + .get(index as usize) + .is_some_and(move |bit| *bit) + } + + pub fn fill(&self, value: bool) { + self.actual.write().unwrap().fill(value) + } + + pub fn len(&self) -> u64 { + self.actual.read().unwrap().len() as u64 + } +} diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index 78b6f2f..ad4be53 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,15 +1,16 @@ -use std::sync::Arc; -use servicepoint::{CompressionCode, Origin}; use crate::bitmap::Bitmap; +use crate::bitvec::BitVec; use crate::errors::ServicePointError; +use servicepoint::{CompressionCode, Origin}; +use std::sync::Arc; #[derive(uniffi::Object)] pub struct Command { - pub(crate)actual: servicepoint::Command + pub(crate) actual: servicepoint::Command, } impl Command { - fn internal_new(actual: servicepoint::Command)-> Arc { + fn internal_new(actual: servicepoint::Command) -> Arc { Arc::new(Command { actual }) } } @@ -24,7 +25,9 @@ impl Command { #[uniffi::constructor] pub fn brightness(brightness: u8) -> Result, ServicePointError> { servicepoint::Brightness::try_from(brightness) - .map_err(move |value| ServicePointError::InvalidBrightness{value}) + .map_err(move |value| ServicePointError::InvalidBrightness { + value, + }) .map(servicepoint::Command::Brightness) .map(Self::internal_new) } @@ -38,13 +41,68 @@ impl Command { pub fn hard_reset() -> Arc { Self::internal_new(servicepoint::Command::HardReset) } - + #[uniffi::constructor] - pub fn bitmap_linear_win(offset_x: u64, offset_y: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear_win( + offset_x: u64, + offset_y: u64, + bitmap: &Arc, + ) -> Arc { let origin = Origin::new(offset_x as usize, offset_y as usize); let bitmap = bitmap.actual.read().unwrap().clone(); // TODO: compression codes - let actual = servicepoint::Command::BitmapLinearWin(origin, bitmap, CompressionCode::Uncompressed); + let actual = servicepoint::Command::BitmapLinearWin( + origin, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinear( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear_and(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearAnd( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear_or(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearOr( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + #[uniffi::constructor] + pub fn bitmap_linear_xor(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearXor( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); Self::internal_new(actual) } } diff --git a/crates/servicepoint_binding_uniffi/src/connection.rs b/crates/servicepoint_binding_uniffi/src/connection.rs index a578135..6ba4e07 100644 --- a/crates/servicepoint_binding_uniffi/src/connection.rs +++ b/crates/servicepoint_binding_uniffi/src/connection.rs @@ -14,16 +14,23 @@ impl Connection { pub fn new(host: String) -> Result, ServicePointError> { servicepoint::Connection::open(host) .map(|actual| Arc::new(Connection { actual })) - .map_err(|err| ServicePointError::IoError { error: err.to_string() }) + .map_err(|err| ServicePointError::IoError { + error: err.to_string(), + }) } #[uniffi::constructor] pub fn new_fake() -> Arc { - Arc::new(Self { actual: servicepoint::Connection::Fake }) + Arc::new(Self { + actual: servicepoint::Connection::Fake, + }) } pub fn send(&self, command: Arc) -> Result<(), ServicePointError> { - self.actual.send(command.actual.clone()) - .map_err(|err| ServicePointError::IoError { error: format!("{err:?}") }) + self.actual.send(command.actual.clone()).map_err(|err| { + ServicePointError::IoError { + error: format!("{err:?}"), + } + }) } } diff --git a/crates/servicepoint_binding_uniffi/src/errors.rs b/crates/servicepoint_binding_uniffi/src/errors.rs index e602342..9c28f5f 100644 --- a/crates/servicepoint_binding_uniffi/src/errors.rs +++ b/crates/servicepoint_binding_uniffi/src/errors.rs @@ -1,8 +1,7 @@ - #[derive(uniffi::Error, thiserror::Error, Debug)] pub enum ServicePointError { #[error("An IO error occurred: {error}")] - IoError {error: String}, + IoError { error: String }, #[error("The specified brightness value {value} is out of range")] - InvalidBrightness {value:u8}, -} \ No newline at end of file + InvalidBrightness { value: u8 }, +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 65f283f..865a82e 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -1,6 +1,7 @@ uniffi::setup_scaffolding!(); +mod bitmap; +mod bitvec; mod command; mod connection; mod errors; -mod bitmap; From f8f5dd0d4fa2ae4d48894a186491b8cc0d95aa1a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 21:49:23 +0100 Subject: [PATCH 07/18] add fake connection to C API --- .../examples/lang_c/include/servicepoint.h | 14 ++++++++++++++ .../servicepoint_binding_c/src/connection.rs | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index 0d716d1..ca57468 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -1201,6 +1201,20 @@ SPCommand *sp_command_hard_reset(void); */ SPCommand *sp_command_try_from_packet(SPPacket *packet); +/** + * Creates a new instance of [SPConnection] for testing that does not actually send anything. + * + * returns: a new instance. Will never return NULL. + * + * # Safety + * + * The caller has to make sure that: + * + * - the returned instance is freed in some way, either by using a consuming function or + * by explicitly calling `sp_connection_free`. + */ +SPConnection *sp_connection_fake(void); + /** * Closes and deallocates a [SPConnection]. * diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs index 3f54438..8b31243 100644 --- a/crates/servicepoint_binding_c/src/connection.rs +++ b/crates/servicepoint_binding_c/src/connection.rs @@ -3,7 +3,7 @@ //! prefix `sp_connection_` use std::ffi::{c_char, CStr}; -use std::ptr::null_mut; +use std::ptr::{null_mut, NonNull}; use crate::{SPCommand, SPPacket}; @@ -46,6 +46,22 @@ pub unsafe extern "C" fn sp_connection_open( Box::into_raw(Box::new(SPConnection(connection))) } +/// Creates a new instance of [SPConnection] for testing that does not actually send anything. +/// +/// returns: a new instance. Will never return NULL. +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - the returned instance is freed in some way, either by using a consuming function or +/// by explicitly calling `sp_connection_free`. +#[no_mangle] +pub unsafe extern "C" fn sp_connection_fake() -> NonNull { + let result = Box::new(SPConnection(servicepoint::Connection::Fake)); + NonNull::from(Box::leak(result)) +} + /// Sends a [SPPacket] to the display using the [SPConnection]. /// /// The passed `packet` gets consumed. From 18f1ccb2dc7dd9d7f9a3a180e5408dfdbb605475 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 22:06:30 +0100 Subject: [PATCH 08/18] add uniffi brightness grid and related command --- .../servicepoint_binding_uniffi.cs | 232 ++++++++++++++++++ .../src/brightness_grid.rs | 65 +++++ .../src/command.rs | 14 ++ crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 4 files changed, 312 insertions(+) create mode 100644 crates/servicepoint_binding_uniffi/src/brightness_grid.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index 9aaf721..a35e75f 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -494,6 +494,39 @@ static class _UniFFILib { public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width(BitmapSafeHandle @ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BrightnessGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BrightnessGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill(BrightnessGridSafeHandle @ptr,byte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern byte uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get(BrightnessGridSafeHandle @ptr,ulong @x,ulong @y,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height(BrightnessGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set(BrightnessGridSafeHandle @ptr,ulong @x,ulong @y,byte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width(BrightnessGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_command( IntPtr ptr,ref RustCallStatus _uniffi_out_err @@ -523,6 +556,10 @@ static class _UniFFILib { public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(byte @brightness,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness(ulong @offsetX,ulong @offsetY,BrightnessGridSafeHandle @grid,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear(ref RustCallStatus _uniffi_out_err ); @@ -816,6 +853,26 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_height( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_set( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); @@ -840,6 +897,14 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear( ); @@ -864,6 +929,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_char_brightness( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear( ); @@ -952,6 +1021,36 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width` checksum `30837`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill(); + if (checksum != 63376) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill` checksum `63376`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_get(); + if (checksum != 28736) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_get` checksum `28736`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_height(); + if (checksum != 39528) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_height` checksum `39528`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_set(); + if (checksum != 6330) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_set` checksum `6330`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width(); + if (checksum != 26384) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width` checksum `26384`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_connection_send(); if (checksum != 23796) { @@ -988,6 +1087,18 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized` checksum `63762`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load(); + if (checksum != 24788) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load` checksum `24788`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new(); + if (checksum != 4979) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new` checksum `4979`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear(); if (checksum != 14881) { @@ -1024,6 +1135,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness` checksum `11291`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_char_brightness(); + if (checksum != 29467) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_char_brightness` checksum `29467`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear(); if (checksum != 11035) { @@ -1509,6 +1626,114 @@ class FfiConverterTypeBitmap: FfiConverter { +public interface IBrightnessGrid { + + void Fill(byte @value); + + byte Get(ulong @x, ulong @y); + + ulong Height(); + + void Set(ulong @x, ulong @y, byte @value); + + ulong Width(); + +} + +public class BrightnessGridSafeHandle: FFISafeHandle { + public BrightnessGridSafeHandle(): base() { + } + public BrightnessGridSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid(this.handle, ref status); + }); + return true; + } +} +public class BrightnessGrid: FFIObject, IBrightnessGrid { + public BrightnessGrid(BrightnessGridSafeHandle pointer): base(pointer) {} + public BrightnessGrid(ulong @width, ulong @height) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), ref _status) +)) {} + + + public void Fill(byte @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill(this.GetHandle(), FfiConverterUInt8.INSTANCE.Lower(@value), ref _status) +); + } + + + public byte Get(ulong @x, ulong @y) { + return FfiConverterUInt8.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), ref _status) +)); + } + + public ulong Height() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height(this.GetHandle(), ref _status) +)); + } + + public void Set(ulong @x, ulong @y, byte @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), FfiConverterUInt8.INSTANCE.Lower(@value), ref _status) +); + } + + + public ulong Width() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width(this.GetHandle(), ref _status) +)); + } + + + + public static BrightnessGrid Load(ulong @width, ulong @height, byte[] @data) { + return new BrightnessGrid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + + +} + +class FfiConverterTypeBrightnessGrid: FfiConverter { + public static FfiConverterTypeBrightnessGrid INSTANCE = new FfiConverterTypeBrightnessGrid(); + + public override BrightnessGridSafeHandle Lower(BrightnessGrid value) { + return value.GetHandle(); + } + + public override BrightnessGrid Lift(BrightnessGridSafeHandle value) { + return new BrightnessGrid(value); + } + + public override BrightnessGrid Read(BigEndianStream stream) { + return Lift(new BrightnessGridSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(BrightnessGrid value) { + return 8; + } + + public override void Write(BrightnessGrid value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public interface ICommand { } @@ -1574,6 +1799,13 @@ public class Command: FFIObject, ICommand { )); } + public static Command CharBrightness(ulong @offsetX, ulong @offsetY, BrightnessGrid @grid) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness(FfiConverterUInt64.INSTANCE.Lower(@offsetX), FfiConverterUInt64.INSTANCE.Lower(@offsetY), FfiConverterTypeBrightnessGrid.INSTANCE.Lower(@grid), ref _status) +)); + } + public static Command Clear() { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => diff --git a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs new file mode 100644 index 0000000..ee97c53 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs @@ -0,0 +1,65 @@ +use servicepoint::{Brightness, Grid}; +use std::sync::{Arc, RwLock}; + +#[derive(uniffi::Object)] +pub struct BrightnessGrid { + pub(crate) actual: RwLock, +} + +impl BrightnessGrid { + fn internal_new(actual: servicepoint::BrightnessGrid) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) + } +} + +#[uniffi::export] +impl BrightnessGrid { + #[uniffi::constructor] + pub fn new(width: u64, height: u64) -> Arc { + Self::internal_new(servicepoint::BrightnessGrid::new( + width as usize, + height as usize, + )) + } + + #[uniffi::constructor] + pub fn load(width: u64, height: u64, data: Vec) -> Arc { + Self::internal_new(servicepoint::BrightnessGrid::saturating_load( + width as usize, + height as usize, + &data, + )) + } + + pub fn set(&self, x: u64, y: u64, value: u8) { + self.actual.write().unwrap().set( + x as usize, + y as usize, + Brightness::saturating_from(value), + ) + } + + pub fn get(&self, x: u64, y: u64) -> u8 { + self.actual + .read() + .unwrap() + .get(x as usize, y as usize) + .into() + } + + pub fn fill(&self, value: u8) { + self.actual + .write() + .unwrap() + .fill(Brightness::saturating_from(value)) + } + pub fn width(&self) -> u64 { + self.actual.read().unwrap().width() as u64 + } + + pub fn height(&self) -> u64 { + self.actual.read().unwrap().height() as u64 + } +} diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index ad4be53..1cd3b7d 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,5 +1,6 @@ use crate::bitmap::Bitmap; use crate::bitvec::BitVec; +use crate::brightness_grid::BrightnessGrid; use crate::errors::ServicePointError; use servicepoint::{CompressionCode, Origin}; use std::sync::Arc; @@ -59,6 +60,18 @@ impl Command { Self::internal_new(actual) } + #[uniffi::constructor] + pub fn char_brightness( + offset_x: u64, + offset_y: u64, + grid: &Arc, + ) -> Arc { + let origin = Origin::new(offset_x as usize, offset_y as usize); + let grid = grid.actual.read().unwrap().clone(); + let actual = servicepoint::Command::CharBrightness(origin, grid); + Self::internal_new(actual) + } + #[uniffi::constructor] pub fn bitmap_linear(offset: u64, bitmap: &Arc) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); @@ -94,6 +107,7 @@ impl Command { ); Self::internal_new(actual) } + #[uniffi::constructor] pub fn bitmap_linear_xor(offset: u64, bitmap: &Arc) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 865a82e..89823ad 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -2,6 +2,7 @@ uniffi::setup_scaffolding!(); mod bitmap; mod bitvec; +mod brightness_grid; mod command; mod connection; mod errors; From 03aa432655dc6230679e30621fb04004d190d49d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 22:21:28 +0100 Subject: [PATCH 09/18] add uniffi compression code, clone add uniffi clone --- .../servicepoint_binding_uniffi.cs | 170 +++++++++++++++--- .../servicepoint_binding_uniffi/src/bitmap.rs | 5 + .../servicepoint_binding_uniffi/src/bitvec.rs | 5 + .../src/brightness_grid.rs | 5 + .../src/command.rs | 53 ++++-- .../src/compression_code.rs | 14 ++ crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 7 files changed, 213 insertions(+), 40 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/src/compression_code.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index a35e75f..cd0eda5 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -433,6 +433,10 @@ static class _UniFFILib { IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone(BitVecSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load(RustBuffer @data,ref RustCallStatus _uniffi_out_err ); @@ -462,6 +466,10 @@ static class _UniFFILib { IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone(BitmapSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err ); @@ -499,6 +507,10 @@ static class _UniFFILib { IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern BrightnessGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone(BrightnessGridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern BrightnessGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err ); @@ -533,23 +545,23 @@ static class _UniFFILib { ); [DllImport("servicepoint_binding_uniffi")] - public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(ulong @offset,BitVecSafeHandle @bitmap,RustBuffer @compression,ref RustCallStatus _uniffi_out_err ); [DllImport("servicepoint_binding_uniffi")] - public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(ulong @offset,BitVecSafeHandle @bitmap,RustBuffer @compression,ref RustCallStatus _uniffi_out_err ); [DllImport("servicepoint_binding_uniffi")] - public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(ulong @offset,BitVecSafeHandle @bitmap,RustBuffer @compression,ref RustCallStatus _uniffi_out_err ); [DllImport("servicepoint_binding_uniffi")] - public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(ulong @offsetX,ulong @offsetY,BitmapSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(ulong @offsetX,ulong @offsetY,BitmapSafeHandle @bitmap,RustBuffer @compression,ref RustCallStatus _uniffi_out_err ); [DllImport("servicepoint_binding_uniffi")] - public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(ulong @offset,BitVecSafeHandle @bitmap,RustBuffer @compression,ref RustCallStatus _uniffi_out_err ); [DllImport("servicepoint_binding_uniffi")] @@ -564,6 +576,10 @@ static class _UniFFILib { public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear(ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone(CommandSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out(ref RustCallStatus _uniffi_out_err ); @@ -877,6 +893,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load( ); @@ -885,6 +905,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_clone( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load( ); @@ -897,6 +921,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_clone( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load( ); @@ -937,6 +965,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out( ); @@ -1057,6 +1089,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone(); + if (checksum != 123) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone` checksum `123`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load(); if (checksum != 48913) { @@ -1069,6 +1107,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new` checksum `11865`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_clone(); + if (checksum != 57298) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_clone` checksum `57298`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load(); if (checksum != 24109) { @@ -1087,6 +1131,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized` checksum `63762`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_clone(); + if (checksum != 33422) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_clone` checksum `33422`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load(); if (checksum != 24788) { @@ -1101,32 +1151,32 @@ static class _UniFFILib { } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear(); - if (checksum != 14881) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear` checksum `14881`, library returned `{checksum}`"); + if (checksum != 18079) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear` checksum `18079`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and(); - if (checksum != 7352) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and` checksum `7352`, library returned `{checksum}`"); + if (checksum != 18147) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and` checksum `18147`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or(); - if (checksum != 7046) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or` checksum `7046`, library returned `{checksum}`"); + if (checksum != 44912) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or` checksum `44912`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win(); - if (checksum != 51700) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win` checksum `51700`, library returned `{checksum}`"); + if (checksum != 24563) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win` checksum `24563`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor(); - if (checksum != 54209) { - throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor` checksum `54209`, library returned `{checksum}`"); + if (checksum != 54278) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor` checksum `54278`, library returned `{checksum}`"); } } { @@ -1147,6 +1197,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear` checksum `11035`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone(); + if (checksum != 42249) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone` checksum `42249`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out(); if (checksum != 49231) { @@ -1475,6 +1531,13 @@ public class BitVec: FFIObject, IBitVec { + public static BitVec Clone(BitVec @other) { + return new BitVec( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone(FfiConverterTypeBitVec.INSTANCE.Lower(@other), ref _status) +)); + } + public static BitVec Load(byte[] @data) { return new BitVec( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1583,6 +1646,13 @@ public class Bitmap: FFIObject, IBitmap { + public static Bitmap Clone(Bitmap @other) { + return new Bitmap( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone(FfiConverterTypeBitmap.INSTANCE.Lower(@other), ref _status) +)); + } + public static Bitmap Load(ulong @width, ulong @height, byte[] @data) { return new Bitmap( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1698,6 +1768,13 @@ public class BrightnessGrid: FFIObject, IBrightnessGri + public static BrightnessGrid Clone(BrightnessGrid @other) { + return new BrightnessGrid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone(FfiConverterTypeBrightnessGrid.INSTANCE.Lower(@other), ref _status) +)); + } + public static BrightnessGrid Load(ulong @width, ulong @height, byte[] @data) { return new BrightnessGrid( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1756,38 +1833,38 @@ public class Command: FFIObject, ICommand { - public static Command BitmapLinear(ulong @offset, BitVec @bitmap) { + public static Command BitmapLinear(ulong @offset, BitVec @bitmap, CompressionCode @compression) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), FfiConverterTypeCompressionCode.INSTANCE.Lower(@compression), ref _status) )); } - public static Command BitmapLinearAnd(ulong @offset, BitVec @bitmap) { + public static Command BitmapLinearAnd(ulong @offset, BitVec @bitmap, CompressionCode @compression) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), FfiConverterTypeCompressionCode.INSTANCE.Lower(@compression), ref _status) )); } - public static Command BitmapLinearOr(ulong @offset, BitVec @bitmap) { + public static Command BitmapLinearOr(ulong @offset, BitVec @bitmap, CompressionCode @compression) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), FfiConverterTypeCompressionCode.INSTANCE.Lower(@compression), ref _status) )); } - public static Command BitmapLinearWin(ulong @offsetX, ulong @offsetY, Bitmap @bitmap) { + public static Command BitmapLinearWin(ulong @offsetX, ulong @offsetY, Bitmap @bitmap, CompressionCode @compression) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(FfiConverterUInt64.INSTANCE.Lower(@offsetX), FfiConverterUInt64.INSTANCE.Lower(@offsetY), FfiConverterTypeBitmap.INSTANCE.Lower(@bitmap), ref _status) + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(FfiConverterUInt64.INSTANCE.Lower(@offsetX), FfiConverterUInt64.INSTANCE.Lower(@offsetY), FfiConverterTypeBitmap.INSTANCE.Lower(@bitmap), FfiConverterTypeCompressionCode.INSTANCE.Lower(@compression), ref _status) )); } - public static Command BitmapLinearXor(ulong @offset, BitVec @bitmap) { + public static Command BitmapLinearXor(ulong @offset, BitVec @bitmap, CompressionCode @compression) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => - _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), FfiConverterTypeCompressionCode.INSTANCE.Lower(@compression), ref _status) )); } @@ -1813,6 +1890,13 @@ public class Command: FFIObject, ICommand { )); } + public static Command Clone(Command @other) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone(FfiConverterTypeCommand.INSTANCE.Lower(@other), ref _status) +)); + } + public static Command FadeOut() { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1932,6 +2016,42 @@ class FfiConverterTypeConnection: FfiConverter +public enum CompressionCode: int { + + Uncompressed, + Zlib, + Bzip2, + Lzma, + Zstd +} + +class FfiConverterTypeCompressionCode: FfiConverterRustBuffer { + public static FfiConverterTypeCompressionCode INSTANCE = new FfiConverterTypeCompressionCode(); + + public override CompressionCode Read(BigEndianStream stream) { + var value = stream.ReadInt() - 1; + if (Enum.IsDefined(typeof(CompressionCode), value)) { + return (CompressionCode)value; + } else { + throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeCompressionCode.Read()", value)); + } + } + + public override int AllocationSize(CompressionCode value) { + return 4; + } + + public override void Write(CompressionCode value, BigEndianStream stream) { + stream.WriteInt((int)value + 1); + } +} + + + + + + + public class ServicePointException: UniffiException { // Each variant is a nested class diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs index e0ebea4..881d628 100644 --- a/crates/servicepoint_binding_uniffi/src/bitmap.rs +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -38,6 +38,11 @@ impl Bitmap { )) } + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.read().unwrap().clone()) + } + pub fn set(&self, x: u64, y: u64, value: bool) { self.actual .write() diff --git a/crates/servicepoint_binding_uniffi/src/bitvec.rs b/crates/servicepoint_binding_uniffi/src/bitvec.rs index f495958..53c9bf4 100644 --- a/crates/servicepoint_binding_uniffi/src/bitvec.rs +++ b/crates/servicepoint_binding_uniffi/src/bitvec.rs @@ -24,6 +24,11 @@ impl BitVec { Self::internal_new(servicepoint::BitVec::from_slice(&data)) } + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.read().unwrap().clone()) + } + pub fn set(&self, index: u64, value: bool) { self.actual.write().unwrap().set(index as usize, value) } diff --git a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs index ee97c53..c6562bc 100644 --- a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs +++ b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs @@ -33,6 +33,11 @@ impl BrightnessGrid { )) } + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.read().unwrap().clone()) + } + pub fn set(&self, x: u64, y: u64, value: u8) { self.actual.write().unwrap().set( x as usize, diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index 1cd3b7d..be2bbcc 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,8 +1,9 @@ use crate::bitmap::Bitmap; use crate::bitvec::BitVec; use crate::brightness_grid::BrightnessGrid; +use crate::compression_code::CompressionCode; use crate::errors::ServicePointError; -use servicepoint::{CompressionCode, Origin}; +use servicepoint::Origin; use std::sync::Arc; #[derive(uniffi::Object)] @@ -48,14 +49,15 @@ impl Command { offset_x: u64, offset_y: u64, bitmap: &Arc, + compression: CompressionCode, ) -> Arc { let origin = Origin::new(offset_x as usize, offset_y as usize); let bitmap = bitmap.actual.read().unwrap().clone(); - // TODO: compression codes let actual = servicepoint::Command::BitmapLinearWin( origin, bitmap, - CompressionCode::Uncompressed, + servicepoint::CompressionCode::try_from(compression as u16) + .unwrap(), ); Self::internal_new(actual) } @@ -73,50 +75,71 @@ impl Command { } #[uniffi::constructor] - pub fn bitmap_linear(offset: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear( + offset: u64, + bitmap: &Arc, + compression: CompressionCode, + ) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); - // TODO: compression codes let actual = servicepoint::Command::BitmapLinear( offset as usize, bitmap, - CompressionCode::Uncompressed, + servicepoint::CompressionCode::try_from(compression as u16) + .unwrap(), ); Self::internal_new(actual) } #[uniffi::constructor] - pub fn bitmap_linear_and(offset: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear_and( + offset: u64, + bitmap: &Arc, + compression: CompressionCode, + ) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); - // TODO: compression codes let actual = servicepoint::Command::BitmapLinearAnd( offset as usize, bitmap, - CompressionCode::Uncompressed, + servicepoint::CompressionCode::try_from(compression as u16) + .unwrap(), ); Self::internal_new(actual) } #[uniffi::constructor] - pub fn bitmap_linear_or(offset: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear_or( + offset: u64, + bitmap: &Arc, + compression: CompressionCode, + ) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); - // TODO: compression codes let actual = servicepoint::Command::BitmapLinearOr( offset as usize, bitmap, - CompressionCode::Uncompressed, + servicepoint::CompressionCode::try_from(compression as u16) + .unwrap(), ); Self::internal_new(actual) } #[uniffi::constructor] - pub fn bitmap_linear_xor(offset: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear_xor( + offset: u64, + bitmap: &Arc, + compression: CompressionCode, + ) -> Arc { let bitmap = bitmap.actual.read().unwrap().clone(); - // TODO: compression codes let actual = servicepoint::Command::BitmapLinearXor( offset as usize, bitmap, - CompressionCode::Uncompressed, + servicepoint::CompressionCode::try_from(compression as u16) + .unwrap(), ); Self::internal_new(actual) } + + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.clone()) + } } diff --git a/crates/servicepoint_binding_uniffi/src/compression_code.rs b/crates/servicepoint_binding_uniffi/src/compression_code.rs new file mode 100644 index 0000000..078230a --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/compression_code.rs @@ -0,0 +1,14 @@ +#[repr(u16)] +#[derive(Debug, Clone, Copy, PartialEq, uniffi::Enum)] +pub enum CompressionCode { + /// no compression + Uncompressed = 0x0, + /// compress using flate2 with zlib header + Zlib = 0x677a, + /// compress using bzip2 + Bzip2 = 0x627a, + /// compress using lzma + Lzma = 0x6c7a, + /// compress using Zstandard + Zstd = 0x7a73, +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 89823ad..975cd9c 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -4,5 +4,6 @@ mod bitmap; mod bitvec; mod brightness_grid; mod command; +mod compression_code; mod connection; mod errors; From 9553d9fe421b661a79e282b6c77bb9b78abe1a04 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 5 Nov 2024 22:39:10 +0100 Subject: [PATCH 10/18] add uniffi CP437Grid, equals add equals method add uniffi copy_raw method --- .../servicepoint_binding_uniffi.cs | 460 ++++++++++++++++++ .../servicepoint_binding_uniffi/src/bitmap.rs | 12 +- .../servicepoint_binding_uniffi/src/bitvec.rs | 10 + .../src/brightness_grid.rs | 12 +- .../src/command.rs | 17 + .../src/cp437_grid.rs | 76 +++ crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 7 files changed, 586 insertions(+), 2 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/src/cp437_grid.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index cd0eda5..2a7679c 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -445,6 +445,14 @@ static class _UniFFILib { public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new(ulong @size,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw(BitVecSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals(BitVecSafeHandle @ptr,BitVecSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(BitVecSafeHandle @ptr,sbyte @value,ref RustCallStatus _uniffi_out_err ); @@ -482,6 +490,14 @@ static class _UniFFILib { public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized(ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw(BitmapSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals(BitmapSafeHandle @ptr,BitmapSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill(BitmapSafeHandle @ptr,sbyte @value,ref RustCallStatus _uniffi_out_err ); @@ -519,6 +535,14 @@ static class _UniFFILib { public static extern BrightnessGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw(BrightnessGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals(BrightnessGridSafeHandle @ptr,BrightnessGridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill(BrightnessGridSafeHandle @ptr,byte @value,ref RustCallStatus _uniffi_out_err ); @@ -580,6 +604,10 @@ static class _UniFFILib { public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone(CommandSafeHandle @other,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data(ulong @offsetX,ulong @offsetY,Cp437GridSafeHandle @grid,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out(ref RustCallStatus _uniffi_out_err ); @@ -588,6 +616,10 @@ static class _UniFFILib { public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset(ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_command_equals(CommandSafeHandle @ptr,CommandSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_connection( IntPtr ptr,ref RustCallStatus _uniffi_out_err @@ -605,6 +637,51 @@ static class _UniFFILib { public static extern void uniffi_servicepoint_binding_uniffi_fn_method_connection_send(ConnectionSafeHandle @ptr,CommandSafeHandle @command,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_cp437grid( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern Cp437GridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone(Cp437GridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern Cp437GridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern Cp437GridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals(Cp437GridSafeHandle @ptr,Cp437GridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill(Cp437GridSafeHandle @ptr,byte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern byte uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get(Cp437GridSafeHandle @ptr,ulong @x,ulong @y,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set(Cp437GridSafeHandle @ptr,ulong @x,ulong @y,byte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_alloc(int @size,ref RustCallStatus _uniffi_out_err ); @@ -833,6 +910,14 @@ static class _UniFFILib { public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_equals( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill( ); @@ -849,6 +934,14 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_copy_raw( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_equals( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill( ); @@ -869,6 +962,14 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_copy_raw( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_equals( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill( ); @@ -889,10 +990,42 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_command_equals( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_copy_raw( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_equals( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_height( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone( ); @@ -969,6 +1102,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_cp437_data( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out( ); @@ -985,6 +1122,18 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_clone( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_load( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_new( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern uint ffi_servicepoint_binding_uniffi_uniffi_contract_version( ); @@ -999,6 +1148,18 @@ static class _UniFFILib { } static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw(); + if (checksum != 12617) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw` checksum `12617`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_equals(); + if (checksum != 1191) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_equals` checksum `1191`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill(); if (checksum != 12255) { @@ -1023,6 +1184,18 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set` checksum `16307`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_copy_raw(); + if (checksum != 3467) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_copy_raw` checksum `3467`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_equals(); + if (checksum != 420) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_equals` checksum `420`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill(); if (checksum != 43887) { @@ -1053,6 +1226,18 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width` checksum `30837`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_copy_raw(); + if (checksum != 28155) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_copy_raw` checksum `28155`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_equals(); + if (checksum != 13314) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_equals` checksum `13314`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill(); if (checksum != 63376) { @@ -1083,12 +1268,60 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width` checksum `26384`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_command_equals(); + if (checksum != 20763) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_command_equals` checksum `20763`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_connection_send(); if (checksum != 23796) { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_copy_raw(); + if (checksum != 50937) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_copy_raw` checksum `50937`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_equals(); + if (checksum != 21544) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_equals` checksum `21544`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_fill(); + if (checksum != 46422) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_fill` checksum `46422`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_get(); + if (checksum != 1945) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_get` checksum `1945`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_height(); + if (checksum != 45951) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_height` checksum `45951`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set(); + if (checksum != 8371) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set` checksum `8371`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width(); + if (checksum != 36872) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width` checksum `36872`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone(); if (checksum != 123) { @@ -1203,6 +1436,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone` checksum `42249`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_cp437_data(); + if (checksum != 33157) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_cp437_data` checksum `33157`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out(); if (checksum != 49231) { @@ -1227,6 +1466,24 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake` checksum `54331`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_clone(); + if (checksum != 28173) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_clone` checksum `28173`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_load(); + if (checksum != 62136) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_load` checksum `62136`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_new(); + if (checksum != 17350) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_new` checksum `17350`, library returned `{checksum}`"); + } + } } } @@ -1470,6 +1727,10 @@ static class FFIObjectUtil { } public interface IBitVec { + byte[] CopyRaw(); + + bool Equals(BitVec @other); + void Fill(bool @value); bool Get(ulong @index); @@ -1501,6 +1762,20 @@ public class BitVec: FFIObject, IBitVec { )) {} + public byte[] CopyRaw() { + return FfiConverterByteArray.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw(this.GetHandle(), ref _status) +)); + } + + public bool Equals(BitVec @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals(this.GetHandle(), FfiConverterTypeBitVec.INSTANCE.Lower(@other), ref _status) +)); + } + public void Fill(bool @value) { _UniffiHelpers.RustCall( (ref RustCallStatus _status) => _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(this.GetHandle(), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) @@ -1576,6 +1851,10 @@ class FfiConverterTypeBitVec: FfiConverter { public interface IBitmap { + byte[] CopyRaw(); + + bool Equals(Bitmap @other); + void Fill(bool @value); bool Get(ulong @x, ulong @y); @@ -1609,6 +1888,20 @@ public class Bitmap: FFIObject, IBitmap { )) {} + public byte[] CopyRaw() { + return FfiConverterByteArray.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw(this.GetHandle(), ref _status) +)); + } + + public bool Equals(Bitmap @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals(this.GetHandle(), FfiConverterTypeBitmap.INSTANCE.Lower(@other), ref _status) +)); + } + public void Fill(bool @value) { _UniffiHelpers.RustCall( (ref RustCallStatus _status) => _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill(this.GetHandle(), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) @@ -1698,6 +1991,10 @@ class FfiConverterTypeBitmap: FfiConverter { public interface IBrightnessGrid { + byte[] CopyRaw(); + + bool Equals(BrightnessGrid @other); + void Fill(byte @value); byte Get(ulong @x, ulong @y); @@ -1731,6 +2028,20 @@ public class BrightnessGrid: FFIObject, IBrightnessGri )) {} + public byte[] CopyRaw() { + return FfiConverterByteArray.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw(this.GetHandle(), ref _status) +)); + } + + public bool Equals(BrightnessGrid @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals(this.GetHandle(), FfiConverterTypeBrightnessGrid.INSTANCE.Lower(@other), ref _status) +)); + } + public void Fill(byte @value) { _UniffiHelpers.RustCall( (ref RustCallStatus _status) => _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill(this.GetHandle(), FfiConverterUInt8.INSTANCE.Lower(@value), ref _status) @@ -1813,6 +2124,8 @@ class FfiConverterTypeBrightnessGrid: FfiConverter, ICommand { public Command(CommandSafeHandle pointer): base(pointer) {} + public bool Equals(Command @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_command_equals(this.GetHandle(), FfiConverterTypeCommand.INSTANCE.Lower(@other), ref _status) +)); + } + public static Command BitmapLinear(ulong @offset, BitVec @bitmap, CompressionCode @compression) { @@ -1897,6 +2217,13 @@ public class Command: FFIObject, ICommand { )); } + public static Command Cp437Data(ulong @offsetX, ulong @offsetY, Cp437Grid @grid) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data(FfiConverterUInt64.INSTANCE.Lower(@offsetX), FfiConverterUInt64.INSTANCE.Lower(@offsetY), FfiConverterTypeCp437Grid.INSTANCE.Lower(@grid), ref _status) +)); + } + public static Command FadeOut() { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -2014,6 +2341,139 @@ class FfiConverterTypeConnection: FfiConverter +public interface ICp437Grid { + + byte[] CopyRaw(); + + bool Equals(Cp437Grid @other); + + void Fill(byte @value); + + byte Get(ulong @x, ulong @y); + + ulong Height(); + + void Set(ulong @x, ulong @y, byte @value); + + ulong Width(); + +} + +public class Cp437GridSafeHandle: FFISafeHandle { + public Cp437GridSafeHandle(): base() { + } + public Cp437GridSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_cp437grid(this.handle, ref status); + }); + return true; + } +} +public class Cp437Grid: FFIObject, ICp437Grid { + public Cp437Grid(Cp437GridSafeHandle pointer): base(pointer) {} + public Cp437Grid(ulong @width, ulong @height) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), ref _status) +)) {} + + + public byte[] CopyRaw() { + return FfiConverterByteArray.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw(this.GetHandle(), ref _status) +)); + } + + public bool Equals(Cp437Grid @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals(this.GetHandle(), FfiConverterTypeCp437Grid.INSTANCE.Lower(@other), ref _status) +)); + } + + public void Fill(byte @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill(this.GetHandle(), FfiConverterUInt8.INSTANCE.Lower(@value), ref _status) +); + } + + + public byte Get(ulong @x, ulong @y) { + return FfiConverterUInt8.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), ref _status) +)); + } + + public ulong Height() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height(this.GetHandle(), ref _status) +)); + } + + public void Set(ulong @x, ulong @y, byte @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), FfiConverterUInt8.INSTANCE.Lower(@value), ref _status) +); + } + + + public ulong Width() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width(this.GetHandle(), ref _status) +)); + } + + + + public static Cp437Grid Clone(Cp437Grid @other) { + return new Cp437Grid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone(FfiConverterTypeCp437Grid.INSTANCE.Lower(@other), ref _status) +)); + } + + public static Cp437Grid Load(ulong @width, ulong @height, byte[] @data) { + return new Cp437Grid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + + +} + +class FfiConverterTypeCp437Grid: FfiConverter { + public static FfiConverterTypeCp437Grid INSTANCE = new FfiConverterTypeCp437Grid(); + + public override Cp437GridSafeHandle Lower(Cp437Grid value) { + return value.GetHandle(); + } + + public override Cp437Grid Lift(Cp437GridSafeHandle value) { + return new Cp437Grid(value); + } + + public override Cp437Grid Read(BigEndianStream stream) { + return Lift(new Cp437GridSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(Cp437Grid value) { + return 8; + } + + public override void Write(Cp437Grid value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public enum CompressionCode: int { diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs index 881d628..394b8a0 100644 --- a/crates/servicepoint_binding_uniffi/src/bitmap.rs +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -1,4 +1,4 @@ -use servicepoint::Grid; +use servicepoint::{DataRef, Grid}; use std::sync::{Arc, RwLock}; #[derive(uniffi::Object)] @@ -64,4 +64,14 @@ impl Bitmap { pub fn height(&self) -> u64 { self.actual.read().unwrap().height() as u64 } + + pub fn equals(&self, other: &Bitmap) -> bool { + let a = self.actual.read().unwrap(); + let b = other.actual.read().unwrap(); + *a == *b + } + + pub fn copy_raw(&self) -> Vec { + self.actual.read().unwrap().data_ref().to_vec() + } } diff --git a/crates/servicepoint_binding_uniffi/src/bitvec.rs b/crates/servicepoint_binding_uniffi/src/bitvec.rs index 53c9bf4..1ad7751 100644 --- a/crates/servicepoint_binding_uniffi/src/bitvec.rs +++ b/crates/servicepoint_binding_uniffi/src/bitvec.rs @@ -48,4 +48,14 @@ impl BitVec { pub fn len(&self) -> u64 { self.actual.read().unwrap().len() as u64 } + + pub fn equals(&self, other: &BitVec) -> bool { + let a = self.actual.read().unwrap(); + let b = other.actual.read().unwrap(); + *a == *b + } + + pub fn copy_raw(&self) -> Vec { + self.actual.read().unwrap().clone().into_vec() + } } diff --git a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs index c6562bc..6660fdf 100644 --- a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs +++ b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs @@ -1,4 +1,4 @@ -use servicepoint::{Brightness, Grid}; +use servicepoint::{Brightness, DataRef, Grid}; use std::sync::{Arc, RwLock}; #[derive(uniffi::Object)] @@ -67,4 +67,14 @@ impl BrightnessGrid { pub fn height(&self) -> u64 { self.actual.read().unwrap().height() as u64 } + + pub fn equals(&self, other: &BrightnessGrid) -> bool { + let a = self.actual.read().unwrap(); + let b = other.actual.read().unwrap(); + *a == *b + } + + pub fn copy_raw(&self) -> Vec { + self.actual.read().unwrap().data_ref().iter().map(u8::from).collect() + } } diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index be2bbcc..b9b399b 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -2,6 +2,7 @@ use crate::bitmap::Bitmap; use crate::bitvec::BitVec; use crate::brightness_grid::BrightnessGrid; use crate::compression_code::CompressionCode; +use crate::cp437_grid::Cp437Grid; use crate::errors::ServicePointError; use servicepoint::Origin; use std::sync::Arc; @@ -138,8 +139,24 @@ impl Command { Self::internal_new(actual) } + #[uniffi::constructor] + pub fn cp437_data( + offset_x: u64, + offset_y: u64, + grid: &Arc, + ) -> Arc { + let origin = Origin::new(offset_x as usize, offset_y as usize); + let grid = grid.actual.read().unwrap().clone(); + let actual = servicepoint::Command::Cp437Data(origin, grid); + Self::internal_new(actual) + } + #[uniffi::constructor] pub fn clone(other: &Arc) -> Arc { Self::internal_new(other.actual.clone()) } + + pub fn equals(&self, other: &Command) -> bool { + self.actual == other.actual + } } diff --git a/crates/servicepoint_binding_uniffi/src/cp437_grid.rs b/crates/servicepoint_binding_uniffi/src/cp437_grid.rs new file mode 100644 index 0000000..fa11d92 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/cp437_grid.rs @@ -0,0 +1,76 @@ +use servicepoint::{DataRef, Grid}; +use std::sync::{Arc, RwLock}; + +#[derive(uniffi::Object)] +pub struct Cp437Grid { + pub(crate) actual: RwLock, +} + +impl Cp437Grid { + fn internal_new(actual: servicepoint::Cp437Grid) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) + } +} + +#[uniffi::export] +impl Cp437Grid { + #[uniffi::constructor] + pub fn new(width: u64, height: u64) -> Arc { + Self::internal_new(servicepoint::Cp437Grid::new( + width as usize, + height as usize, + )) + } + + #[uniffi::constructor] + pub fn load(width: u64, height: u64, data: Vec) -> Arc { + Self::internal_new(servicepoint::Cp437Grid::load( + width as usize, + height as usize, + &data, + )) + } + + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.read().unwrap().clone()) + } + + pub fn set(&self, x: u64, y: u64, value: u8) { + self.actual + .write() + .unwrap() + .set(x as usize, y as usize, value) + } + + pub fn get(&self, x: u64, y: u64) -> u8 { + self.actual + .read() + .unwrap() + .get(x as usize, y as usize) + .into() + } + + pub fn fill(&self, value: u8) { + self.actual.write().unwrap().fill(value) + } + pub fn width(&self) -> u64 { + self.actual.read().unwrap().width() as u64 + } + + pub fn height(&self) -> u64 { + self.actual.read().unwrap().height() as u64 + } + + pub fn equals(&self, other: &Cp437Grid) -> bool { + let a = self.actual.read().unwrap(); + let b = other.actual.read().unwrap(); + *a == *b + } + + pub fn copy_raw(&self) -> Vec { + self.actual.read().unwrap().data_ref().to_vec() + } +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 975cd9c..702cd00 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -6,4 +6,5 @@ mod brightness_grid; mod command; mod compression_code; mod connection; +mod cp437_grid; mod errors; From d0d70c079e279656d43b7247a5c7dce1622d0b2a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 10 Nov 2024 15:08:39 +0100 Subject: [PATCH 11/18] add uniffi CharGrid --- crates/servicepoint_binding_uniffi/Cargo.toml | 2 +- .../ServicePoint.Tests/CharGridTests.cs | 31 + .../csharp/ServicePoint.Tests/CommandTests.cs | 2 +- .../servicepoint_binding_uniffi.cs | 543 ++++++++++++++++++ .../servicepoint_binding_uniffi/src/bitmap.rs | 2 +- .../src/brightness_grid.rs | 8 +- .../src/char_grid.rs | 163 ++++++ .../src/cp437_grid.rs | 13 +- crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 9 files changed, 755 insertions(+), 10 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CharGridTests.cs create mode 100644 crates/servicepoint_binding_uniffi/src/char_grid.rs diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml index 58248c3..8cce76c 100644 --- a/crates/servicepoint_binding_uniffi/Cargo.toml +++ b/crates/servicepoint_binding_uniffi/Cargo.toml @@ -17,7 +17,7 @@ uniffi = { version = "0.25.0", features = ["build"] } [dependencies] uniffi = { version = "0.25.0" } -thiserror = "1.0.66" +thiserror.workspace = true [dependencies.servicepoint] version = "0.11.0" diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CharGridTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CharGridTests.cs new file mode 100644 index 0000000..de849c6 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CharGridTests.cs @@ -0,0 +1,31 @@ +namespace ServicePoint.Tests; + +public class CharGridTests +{ + [Fact] + public void BasicFunctions() + { + var grid = new CharGrid(8, 2); + Assert.Equal("\0", grid.Get(0, 0)); + Assert.Equal("\0", grid.Get(grid.Width() - 1, grid.Height() - 1)); + grid.Fill(" "); + Assert.Equal(" ", grid.Get(1, 1)); + grid.Set(1, 1, "-"); + Assert.Equal("-", grid.Get(1, 1)); + Assert.Throws(() => grid.Get(8, 2)); + } + + [Fact] + public void RowAndCol() + { + var grid = new CharGrid(3, 2); + Assert.Equal("\0\0\0", grid.GetRow(0)); + grid.Fill(" "); + Assert.Equal(" ", grid.GetCol(1)); + Assert.Throws(() => grid.GetCol(3)); + Assert.Throws(() => grid.SetRow(1, "Text")); + grid.SetRow(1, "Foo"); + Assert.Equal("Foo", grid.GetRow(1)); + Assert.Equal(" o", grid.GetCol(2)); + } +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs index b17deb3..4687162 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Tests/CommandTests.cs @@ -37,6 +37,6 @@ public class CommandTests [Fact] public void BitmapLinearWinSendable() { - _connection.Send(Command.BitmapLinearWin(0, 0, Bitmap.NewMaxSized())); + _connection.Send(Command.BitmapLinearWin(0, 0, Bitmap.NewMaxSized(), CompressionCode.Uncompressed)); } } diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index 2a7679c..f9a6975 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -563,6 +563,71 @@ static class _UniFFILib { public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width(BrightnessGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_chargrid( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CharGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone(CharGridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CharGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load(RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CharGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string(CharGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals(CharGridSafeHandle @ptr,CharGridSafeHandle @other,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill(CharGridSafeHandle @ptr,RustBuffer @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get(CharGridSafeHandle @ptr,ulong @x,ulong @y,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col(CharGridSafeHandle @ptr,ulong @x,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row(CharGridSafeHandle @ptr,ulong @y,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height(CharGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set(CharGridSafeHandle @ptr,ulong @x,ulong @y,RustBuffer @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col(CharGridSafeHandle @ptr,ulong @x,RustBuffer @col,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row(CharGridSafeHandle @ptr,ulong @y,RustBuffer @row,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern Cp437GridSafeHandle uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437(CharGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width(CharGridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_command( IntPtr ptr,ref RustCallStatus _uniffi_out_err @@ -678,6 +743,10 @@ static class _UniFFILib { public static extern void uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set(Cp437GridSafeHandle @ptr,ulong @x,ulong @y,byte @value,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CharGridSafeHandle uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err ); @@ -990,6 +1059,54 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_as_string( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_equals( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_col( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_row( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_height( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_col( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_row( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_to_cp437( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_width( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_command_equals( ); @@ -1022,6 +1139,10 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_to_utf8( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width( ); @@ -1066,6 +1187,18 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_clone( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_load( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_new( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear( ); @@ -1268,6 +1401,78 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width` checksum `26384`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_as_string(); + if (checksum != 46581) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_as_string` checksum `46581`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_equals(); + if (checksum != 17533) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_equals` checksum `17533`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_fill(); + if (checksum != 56996) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_fill` checksum `56996`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get(); + if (checksum != 1334) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get` checksum `1334`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_col(); + if (checksum != 64158) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_col` checksum `64158`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_row(); + if (checksum != 39411) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_row` checksum `39411`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_height(); + if (checksum != 13068) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_height` checksum `13068`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set(); + if (checksum != 64815) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set` checksum `64815`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_col(); + if (checksum != 43727) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_col` checksum `43727`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_row(); + if (checksum != 19756) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_row` checksum `19756`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_to_cp437(); + if (checksum != 19261) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_to_cp437` checksum `19261`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_width(); + if (checksum != 48963) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_width` checksum `48963`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_command_equals(); if (checksum != 20763) { @@ -1316,6 +1521,12 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set` checksum `8371`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_to_utf8(); + if (checksum != 21516) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_to_utf8` checksum `21516`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width(); if (checksum != 36872) { @@ -1382,6 +1593,24 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new` checksum `4979`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_clone(); + if (checksum != 61241) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_clone` checksum `61241`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_load(); + if (checksum != 47815) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_load` checksum `47815`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_new(); + if (checksum != 13303) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_new` checksum `13303`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear(); if (checksum != 18079) { @@ -2122,6 +2351,196 @@ class FfiConverterTypeBrightnessGrid: FfiConverter + void Fill(String @value); + + String Get(ulong @x, ulong @y); + + /// + String GetCol(ulong @x); + + /// + String GetRow(ulong @y); + + ulong Height(); + + /// + void Set(ulong @x, ulong @y, String @value); + + /// + void SetCol(ulong @x, String @col); + + /// + void SetRow(ulong @y, String @row); + + Cp437Grid ToCp437(); + + ulong Width(); + +} + +public class CharGridSafeHandle: FFISafeHandle { + public CharGridSafeHandle(): base() { + } + public CharGridSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_chargrid(this.handle, ref status); + }); + return true; + } +} +public class CharGrid: FFIObject, ICharGrid { + public CharGrid(CharGridSafeHandle pointer): base(pointer) {} + public CharGrid(ulong @width, ulong @height) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), ref _status) +)) {} + + + public String AsString() { + return FfiConverterString.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string(this.GetHandle(), ref _status) +)); + } + + public bool Equals(CharGrid @other) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals(this.GetHandle(), FfiConverterTypeCharGrid.INSTANCE.Lower(@other), ref _status) +)); + } + + /// + public void Fill(String @value) { + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill(this.GetHandle(), FfiConverterString.INSTANCE.Lower(@value), ref _status) +); + } + + + public String Get(ulong @x, ulong @y) { + return FfiConverterString.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), ref _status) +)); + } + + /// + public String GetCol(ulong @x) { + return FfiConverterString.INSTANCE.Lift( + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), ref _status) +)); + } + + /// + public String GetRow(ulong @y) { + return FfiConverterString.INSTANCE.Lift( + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@y), ref _status) +)); + } + + public ulong Height() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height(this.GetHandle(), ref _status) +)); + } + + /// + public void Set(ulong @x, ulong @y, String @value) { + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterUInt64.INSTANCE.Lower(@y), FfiConverterString.INSTANCE.Lower(@value), ref _status) +); + } + + + /// + public void SetCol(ulong @x, String @col) { + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@x), FfiConverterString.INSTANCE.Lower(@col), ref _status) +); + } + + + /// + public void SetRow(ulong @y, String @row) { + _UniffiHelpers.RustCallWithError(FfiConverterTypeCharGridException.INSTANCE, (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@y), FfiConverterString.INSTANCE.Lower(@row), ref _status) +); + } + + + public Cp437Grid ToCp437() { + return FfiConverterTypeCp437Grid.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437(this.GetHandle(), ref _status) +)); + } + + public ulong Width() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width(this.GetHandle(), ref _status) +)); + } + + + + public static CharGrid Clone(CharGrid @other) { + return new CharGrid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone(FfiConverterTypeCharGrid.INSTANCE.Lower(@other), ref _status) +)); + } + + public static CharGrid Load(String @data) { + return new CharGrid( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load(FfiConverterString.INSTANCE.Lower(@data), ref _status) +)); + } + + +} + +class FfiConverterTypeCharGrid: FfiConverter { + public static FfiConverterTypeCharGrid INSTANCE = new FfiConverterTypeCharGrid(); + + public override CharGridSafeHandle Lower(CharGrid value) { + return value.GetHandle(); + } + + public override CharGrid Lift(CharGridSafeHandle value) { + return new CharGrid(value); + } + + public override CharGrid Read(BigEndianStream stream) { + return Lift(new CharGridSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(CharGrid value) { + return 8; + } + + public override void Write(CharGrid value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public interface ICommand { bool Equals(Command @other); @@ -2355,6 +2774,8 @@ public interface ICp437Grid { void Set(ulong @x, ulong @y, byte @value); + CharGrid ToUtf8(); + ulong Width(); } @@ -2422,6 +2843,13 @@ public class Cp437Grid: FFIObject, ICp437Grid { } + public CharGrid ToUtf8() { + return FfiConverterTypeCharGrid.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8(this.GetHandle(), ref _status) +)); + } + public ulong Width() { return FfiConverterUInt64.INSTANCE.Lift( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -2476,6 +2904,121 @@ class FfiConverterTypeCp437Grid: FfiConverter { +public class CharGridException: UniffiException { + // Each variant is a nested class + + + public class StringNotOneChar : CharGridException { + // Members + public String @value; + + // Constructor + public StringNotOneChar( + String @value) { + this.@value = @value; + } + } + + + public class InvalidSeriesLength : CharGridException { + // Members + public ulong @actual; + public ulong @expected; + + // Constructor + public InvalidSeriesLength( + ulong @actual, + ulong @expected) { + this.@actual = @actual; + this.@expected = @expected; + } + } + + + public class OutOfBounds : CharGridException { + // Members + public ulong @index; + public ulong @size; + + // Constructor + public OutOfBounds( + ulong @index, + ulong @size) { + this.@index = @index; + this.@size = @size; + } + } + + + +} + +class FfiConverterTypeCharGridException : FfiConverterRustBuffer, CallStatusErrorHandler { + public static FfiConverterTypeCharGridException INSTANCE = new FfiConverterTypeCharGridException(); + + public override CharGridException Read(BigEndianStream stream) { + var value = stream.ReadInt(); + switch (value) { + case 1: + return new CharGridException.StringNotOneChar( + FfiConverterString.INSTANCE.Read(stream)); + case 2: + return new CharGridException.InvalidSeriesLength( + FfiConverterUInt64.INSTANCE.Read(stream), + FfiConverterUInt64.INSTANCE.Read(stream)); + case 3: + return new CharGridException.OutOfBounds( + FfiConverterUInt64.INSTANCE.Read(stream), + FfiConverterUInt64.INSTANCE.Read(stream)); + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeCharGridException.Read()", value)); + } + } + + public override int AllocationSize(CharGridException value) { + switch (value) { + case CharGridException.StringNotOneChar variant_value: + return 4 + + FfiConverterString.INSTANCE.AllocationSize(variant_value.@value); + case CharGridException.InvalidSeriesLength variant_value: + return 4 + + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@actual) + + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@expected); + case CharGridException.OutOfBounds variant_value: + return 4 + + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@index) + + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@size); + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeCharGridException.AllocationSize()", value)); + } + } + + public override void Write(CharGridException value, BigEndianStream stream) { + switch (value) { + case CharGridException.StringNotOneChar variant_value: + stream.WriteInt(1); + FfiConverterString.INSTANCE.Write(variant_value.@value, stream); + break; + case CharGridException.InvalidSeriesLength variant_value: + stream.WriteInt(2); + FfiConverterUInt64.INSTANCE.Write(variant_value.@actual, stream); + FfiConverterUInt64.INSTANCE.Write(variant_value.@expected, stream); + break; + case CharGridException.OutOfBounds variant_value: + stream.WriteInt(3); + FfiConverterUInt64.INSTANCE.Write(variant_value.@index, stream); + FfiConverterUInt64.INSTANCE.Write(variant_value.@size, stream); + break; + default: + throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeCharGridException.Write()", value)); + } + } +} + + + + + public enum CompressionCode: int { Uncompressed, diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs index 394b8a0..1291f7b 100644 --- a/crates/servicepoint_binding_uniffi/src/bitmap.rs +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -70,7 +70,7 @@ impl Bitmap { let b = other.actual.read().unwrap(); *a == *b } - + pub fn copy_raw(&self) -> Vec { self.actual.read().unwrap().data_ref().to_vec() } diff --git a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs index 6660fdf..afa0e3f 100644 --- a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs +++ b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs @@ -75,6 +75,12 @@ impl BrightnessGrid { } pub fn copy_raw(&self) -> Vec { - self.actual.read().unwrap().data_ref().iter().map(u8::from).collect() + self.actual + .read() + .unwrap() + .data_ref() + .iter() + .map(u8::from) + .collect() } } diff --git a/crates/servicepoint_binding_uniffi/src/char_grid.rs b/crates/servicepoint_binding_uniffi/src/char_grid.rs new file mode 100644 index 0000000..9dafce4 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/char_grid.rs @@ -0,0 +1,163 @@ +use servicepoint::{Grid, SeriesError}; +use std::convert::Into; +use std::sync::{Arc, RwLock}; +use crate::cp437_grid::Cp437Grid; + +#[derive(uniffi::Object)] +pub struct CharGrid { + pub(crate) actual: RwLock, +} + +#[derive(uniffi::Error, thiserror::Error, Debug)] +pub enum CharGridError { + #[error("Exactly one character was expected, but {value:?} was provided")] + StringNotOneChar { value: String }, + #[error("The provided series was expected to have a length of {expected}, but was {actual}")] + InvalidSeriesLength { actual: u64, expected: u64 }, + #[error("The index {index} was out of bounds for size {size}")] + OutOfBounds { index: u64, size: u64 }, +} + +#[uniffi::export] +impl CharGrid { + #[uniffi::constructor] + pub fn new(width: u64, height: u64) -> Arc { + Self::internal_new(servicepoint::CharGrid::new( + width as usize, + height as usize, + )) + } + + #[uniffi::constructor] + pub fn load(data: String) -> Arc { + Self::internal_new(servicepoint::CharGrid::from(&*data)) + } + + #[uniffi::constructor] + pub fn clone(other: &Arc) -> Arc { + Self::internal_new(other.actual.read().unwrap().clone()) + } + + pub fn set( + &self, + x: u64, + y: u64, + value: String, + ) -> Result<(), CharGridError> { + let value = Self::str_to_char(value)?; + self.actual + .write() + .unwrap() + .set(x as usize, y as usize, value); + Ok(()) + } + + pub fn get(&self, x: u64, y: u64) -> String { + self.actual + .read() + .unwrap() + .get(x as usize, y as usize) + .into() + } + + pub fn fill(&self, value: String) -> Result<(), CharGridError> { + let value = Self::str_to_char(value)?; + self.actual.write().unwrap().fill(value); + Ok(()) + } + + pub fn width(&self) -> u64 { + self.actual.read().unwrap().width() as u64 + } + + pub fn height(&self) -> u64 { + self.actual.read().unwrap().height() as u64 + } + + pub fn equals(&self, other: &CharGrid) -> bool { + let a = self.actual.read().unwrap(); + let b = other.actual.read().unwrap(); + *a == *b + } + + pub fn as_string(&self) -> String { + let grid = self.actual.read().unwrap(); + String::from(&*grid) + } + + pub fn set_row(&self, y: u64, row: String) -> Result<(), CharGridError> { + self.actual + .write() + .unwrap() + .set_row(y as usize, &*row.chars().collect::>()) + .map_err(CharGridError::from) + } + + pub fn set_col(&self, x: u64, col: String) -> Result<(), CharGridError> { + self.actual + .write() + .unwrap() + .set_row(x as usize, &*col.chars().collect::>()) + .map_err(CharGridError::from) + } + + pub fn get_row(&self, y: u64) -> Result { + self.actual + .read() + .unwrap() + .get_row(y as usize) + .map(move |vec| String::from_iter(vec)) + .ok_or(CharGridError::OutOfBounds {index: y, size: self.height()}) + } + + pub fn get_col(&self, x: u64) -> Result { + self.actual + .read() + .unwrap() + .get_col(x as usize) + .map(move |vec| String::from_iter(vec)) + .ok_or(CharGridError::OutOfBounds {index: x, size: self.width()}) + } + + pub fn to_cp437(&self) -> Arc { + Cp437Grid::internal_new(servicepoint::Cp437Grid::from(&*self.actual.read().unwrap())) + } +} + +impl CharGrid { + pub(crate) fn internal_new(actual: servicepoint::CharGrid) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) + } + + fn str_to_char(value: String) -> Result { + if value.len() != 1 { + return Err(CharGridError::StringNotOneChar { + value, + }); + } + + let value = value.chars().nth(0).unwrap(); + Ok(value) + } +} + +impl From for CharGridError { + fn from(e: SeriesError) -> Self { + match e { + SeriesError::OutOfBounds { index, size } => { + CharGridError::OutOfBounds { + index: index as u64, + size: size as u64, + } + } + SeriesError::InvalidLength { actual, expected } => { + CharGridError::InvalidSeriesLength { + actual: actual as u64, + expected: expected as u64, + } + } + } + } +} diff --git a/crates/servicepoint_binding_uniffi/src/cp437_grid.rs b/crates/servicepoint_binding_uniffi/src/cp437_grid.rs index fa11d92..3819176 100644 --- a/crates/servicepoint_binding_uniffi/src/cp437_grid.rs +++ b/crates/servicepoint_binding_uniffi/src/cp437_grid.rs @@ -1,5 +1,6 @@ use servicepoint::{DataRef, Grid}; use std::sync::{Arc, RwLock}; +use crate::char_grid::CharGrid; #[derive(uniffi::Object)] pub struct Cp437Grid { @@ -7,7 +8,7 @@ pub struct Cp437Grid { } impl Cp437Grid { - fn internal_new(actual: servicepoint::Cp437Grid) -> Arc { + pub(crate) fn internal_new(actual: servicepoint::Cp437Grid) -> Arc { Arc::new(Self { actual: RwLock::new(actual), }) @@ -46,11 +47,7 @@ impl Cp437Grid { } pub fn get(&self, x: u64, y: u64) -> u8 { - self.actual - .read() - .unwrap() - .get(x as usize, y as usize) - .into() + self.actual.read().unwrap().get(x as usize, y as usize) } pub fn fill(&self, value: u8) { @@ -73,4 +70,8 @@ impl Cp437Grid { pub fn copy_raw(&self) -> Vec { self.actual.read().unwrap().data_ref().to_vec() } + + pub fn to_utf8(&self) -> Arc { + CharGrid::internal_new(servicepoint::CharGrid::from(&*self.actual.read().unwrap())) + } } diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 702cd00..29564aa 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -3,6 +3,7 @@ uniffi::setup_scaffolding!(); mod bitmap; mod bitvec; mod brightness_grid; +mod char_grid; mod command; mod compression_code; mod connection; From 6137460457cf4d000a32a72fdba21018f43cb300 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 13 Nov 2024 19:53:58 +0100 Subject: [PATCH 12/18] update uniffi --- Cargo.lock | 896 ++++++++++++++++-- crates/servicepoint_binding_uniffi/Cargo.toml | 4 +- 2 files changed, 832 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01217c7..3819516 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,15 +8,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "anstream" version = "0.6.18" @@ -66,6 +57,133 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "askama" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb98f10f371286b177db5eeb9a6e5396609555686a35e1d4f7b9a9c6d8af0139" +dependencies = [ + "askama_derive 0.11.2", + "askama_escape", + "askama_shared", +] + +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive 0.12.5", + "askama_escape", +] + +[[package]] +name = "askama_derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87bf87e6e8b47264efa9bde63d6225c6276a52e05e91bf37eaa8afd0032d6b71" +dependencies = [ + "askama_shared", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.87", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + +[[package]] +name = "askama_shared" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf722b94118a07fcbc6640190f247334027685d4e218b794dbfe17c32bf38ed0" +dependencies = [ + "askama_escape", + "mime", + "mime_guess", + "nom", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "toml 0.5.11", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "basic-toml" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -126,23 +244,55 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cbindgen" version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" dependencies = [ - "clap", + "clap 4.5.20", "heck 0.4.1", - "indexmap", + "indexmap 2.6.0", "log", "proc-macro2", "quote", "serde", "serde_json", - "syn", + "syn 2.0.87", "tempfile", - "toml", + "toml 0.8.19", ] [[package]] @@ -162,6 +312,23 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive 3.2.25", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "once_cell", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + [[package]] name = "clap" version = "4.5.20" @@ -169,7 +336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", - "clap_derive", + "clap_derive 4.5.18", ] [[package]] @@ -180,8 +347,21 @@ checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", - "clap_lex", - "strsim", + "clap_lex 0.7.2", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -193,7 +373,16 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn", + "syn 2.0.87", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -236,16 +425,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "csbindgen" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" -dependencies = [ - "regex", - "syn", -] - [[package]] name = "data-encoding" version = "2.6.0" @@ -278,6 +457,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "extend" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "311a6d2f1f9d60bff73d2c78a0af97ed27f79672f15c238192a5bbb64db56d00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "fastrand" version = "2.2.0" @@ -300,6 +490,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + [[package]] name = "funty" version = "2.0.0" @@ -327,6 +526,29 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "goblin" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.1" @@ -345,6 +567,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "http" version = "1.1.0" @@ -362,6 +593,16 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.6.0" @@ -369,7 +610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.1", ] [[package]] @@ -425,6 +666,28 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -434,18 +697,52 @@ dependencies = [ "adler2", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "once_cell" version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "oneshot-uniffi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -455,6 +752,30 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -509,35 +830,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - [[package]] name = "rust-lzma" version = "0.6.0" @@ -554,7 +846,7 @@ version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -567,6 +859,35 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + [[package]] name = "serde" version = "1.0.215" @@ -584,7 +905,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.87", ] [[package]] @@ -614,7 +935,7 @@ version = "0.11.0" dependencies = [ "bitvec", "bzip2", - "clap", + "clap 4.5.20", "flate2", "log", "once_cell", @@ -634,12 +955,14 @@ dependencies = [ ] [[package]] -name = "servicepoint_binding_cs" +name = "servicepoint_binding_uniffi" version = "0.11.0" dependencies = [ - "csbindgen", "servicepoint", - "servicepoint_binding_c", + "thiserror", + "uniffi", + "uniffi-bindgen-cs", + "uniffi-bindgen-go", ] [[package]] @@ -659,12 +982,47 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.87" @@ -695,6 +1053,26 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -712,7 +1090,16 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.87", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", ] [[package]] @@ -742,7 +1129,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -773,12 +1160,333 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" + [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "uniffi" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" +dependencies = [ + "anyhow", + "uniffi_build", + "uniffi_core", + "uniffi_macros", +] + +[[package]] +name = "uniffi-bindgen-cs" +version = "0.8.3+v0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "anyhow", + "askama 0.11.1", + "camino", + "clap 3.2.25", + "extend", + "fs-err", + "heck 0.4.1", + "paste", + "serde", + "serde_json", + "textwrap", + "toml 0.5.11", + "uniffi_bindgen 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", +] + +[[package]] +name = "uniffi-bindgen-go" +version = "0.2.1+v0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "anyhow", + "askama 0.12.1", + "camino", + "cargo_metadata", + "clap 3.2.25", + "extend", + "fs-err", + "heck 0.4.1", + "paste", + "serde", + "serde_json", + "textwrap", + "toml 0.5.11", + "uniffi_bindgen 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "anyhow", + "askama 0.12.1", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck 0.4.1", + "once_cell", + "paste", + "serde", + "textwrap", + "toml 0.5.11", + "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "anyhow", + "askama 0.12.1", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck 0.4.1", + "once_cell", + "paste", + "serde", + "textwrap", + "toml 0.5.11", + "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", + "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", + "uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940" +dependencies = [ + "anyhow", + "askama 0.12.1", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck 0.4.1", + "once_cell", + "paste", + "serde", + "toml 0.5.11", + "uniffi_meta 0.25.3", + "uniffi_testing 0.25.3", + "uniffi_udl 0.25.3", +] + +[[package]] +name = "uniffi_build" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen 0.25.3", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "quote", + "syn 2.0.87", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "quote", + "syn 2.0.87", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" +dependencies = [ + "quote", + "syn 2.0.87", +] + +[[package]] +name = "uniffi_core" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b" +dependencies = [ + "anyhow", + "bytes", + "camino", + "log", + "once_cell", + "oneshot-uniffi", + "paste", + "static_assertions", +] + +[[package]] +name = "uniffi_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4" +dependencies = [ + "bincode", + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.87", + "toml 0.5.11", + "uniffi_build", + "uniffi_meta 0.25.3", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive 0.25.3", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "anyhow", + "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", + "weedle2 4.0.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "anyhow", + "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", + "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", + "weedle2 4.0.0 (git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce)", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3" +dependencies = [ + "anyhow", + "uniffi_meta 0.25.3", + "uniffi_testing 0.25.3", + "weedle2 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf-8" version = "0.7.6" @@ -809,6 +1517,62 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "weedle2" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" +dependencies = [ + "nom", +] + +[[package]] +name = "weedle2" +version = "4.0.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" +dependencies = [ + "nom", +] + +[[package]] +name = "weedle2" +version = "4.0.0" +source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" +dependencies = [ + "nom", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" @@ -927,7 +1691,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.87", ] [[package]] diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml index 8cce76c..3b02bd2 100644 --- a/crates/servicepoint_binding_uniffi/Cargo.toml +++ b/crates/servicepoint_binding_uniffi/Cargo.toml @@ -13,10 +13,10 @@ repository = "https://github.com/cccb/servicepoint" crate-type = ["cdylib"] [build-dependencies] -uniffi = { version = "0.25.0", features = ["build"] } +uniffi = { version = "0.25.3", features = ["build"] } [dependencies] -uniffi = { version = "0.25.0" } +uniffi = { version = "0.25.3" } thiserror.workspace = true [dependencies.servicepoint] From b693e9e1c96e948b897b3e806e0b8fa6a6dbcf53 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 17:38:50 +0100 Subject: [PATCH 13/18] add ruby example, update README.md --- README.md | 23 +- crates/servicepoint_binding_uniffi/README.md | 90 + .../generate-bindings.sh | 2 +- .../libraries/.gitignore | 4 + .../libraries/ruby/example/Gemfile | 3 + .../libraries/ruby/example/Gemfile.lock | 19 + .../libraries/ruby/example/example.rb | 25 + .../libraries/ruby/example/example.sh | 3 + .../ruby/lib/servicepoint_binding_uniffi.rb | 1897 +++++++++++++++++ .../libraries/ruby/servicepoint.gemspec | 13 + flake.nix | 19 +- 11 files changed, 2080 insertions(+), 18 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/README.md create mode 100644 crates/servicepoint_binding_uniffi/libraries/.gitignore create mode 100644 crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile create mode 100644 crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock create mode 100644 crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb create mode 100755 crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh create mode 100644 crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb create mode 100644 crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec diff --git a/README.md b/README.md index a4e2836..903a519 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # servicepoint +[![crates.io](https://img.shields.io/crates/v/servicepoint.svg)](https://crates.io/crates/servicepoint) +[![Crates.io Total Downloads](https://img.shields.io/crates/d/servicepoint)](https://crates.io/crates/servicepoint) +[![docs.rs](https://img.shields.io/docsrs/servicepoint)](https://docs.rs/servicepoint/latest/servicepoint/) +[![GPLv3 licensed](https://img.shields.io/crates/l/servicepoint)](../../LICENSE) + In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wall. It is called "Service Point Display" or "Airport Display". This repository contains a library for parsing, encoding and sending packets to this display via UDP in multiple @@ -7,20 +12,20 @@ programming languages. Take a look at the contained crates for language specific information: -| Language | Readme | -|-----------|---------------------------------------------------------------------| -| Rust | [servicepoint](crates/servicepoint/README.md) | -| C / C++ | [servicepoint_binding_c](crates/servicepoint_binding_c/README.md) | -| .NET (C#) | [servicepoint_binding_cs](crates/servicepoint_binding_cs/README.md) | +| Crate | Languages | Readme | +|-----------------------------|-----------------------------------|-------------------------------------------------------------------------| +| servicepoint | Rust | [servicepoint](crates/servicepoint/README.md) | +| servicepoint_binding_c | C / C++ | [servicepoint_binding_c](crates/servicepoint_binding_c/README.md) | +| servicepoint_binding_uniffi | C# / Python / Go / Kotlin / Swift | [servicepoint_binding_cs](crates/servicepoint_binding_uniffi/README.md) | ## Projects using the library - screen simulator (rust): [servicepoint-simulator](https://github.com/kaesaecracker/servicepoint-simulator) - A bunch of projects (C): [arfst23/ServicePoint](https://github.com/arfst23/ServicePoint), including - - a CLI tool to display image files on the display or use the display as a TTY - - a BSD games robots clone - - a split-flap-display simulator - - animations that play on the display + - a CLI tool to display image files on the display or use the display as a TTY + - a BSD games robots clone + - a split-flap-display simulator + - animations that play on the display - tanks game (C#): [servicepoint-tanks](https://github.com/kaesaecracker/cccb-tanks-cs) - cellular automata slideshow (rust): [servicepoint-life](https://github.com/kaesaecracker/servicepoint-life) diff --git a/crates/servicepoint_binding_uniffi/README.md b/crates/servicepoint_binding_uniffi/README.md new file mode 100644 index 0000000..b71c35d --- /dev/null +++ b/crates/servicepoint_binding_uniffi/README.md @@ -0,0 +1,90 @@ +# ServicePoint + +In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wall. It is called "Service Point +Display" or "Airport Display". + +This crate contains bindings for multiple programming languages, enabling non-rust-developers to use the library. + +Also take a look at the main project [README](https://github.com/cccb/servicepoint/blob/main/README.md) for more +information. + +## Note on stability + +This library is still in early development. +You can absolutely use it, and it works, but expect minor breaking changes with every version bump. + +## Notes on differences to rust library + +- Performance will not be as good as the rust version: + - most objects are reference counted. + - objects with mutating methods will also have a MRSW lock +- You will not get rust backtraces in release builds of the native code +- Panic messages will work (PanicException) + +## Supported languages + +| Language | Support level | Notes | +|-----------|---------------|-------------------------------------------------------------------------------------------------| +| .NET (C#) | Full | see dedicated section | +| Ruby | Working | LD_LIBRARY_PATH has to be set, see example project | +| Python | Tested once | Required project file not included. The shared library will be loaded from the script location. | +| Go | untested | | +| Kotlin | untested | | +| Swift | untested | | + +## Installation + +Including this repository as a submodule and building from source is the recommended way of using the library. + +```bash +git submodule add https://github.com/cccb/servicepoint.git +git commit -m "add servicepoint submodule" +``` + +Run `generate-bindings.sh` to regenerate all bindings. This will also build `libservicepoint.so` (or equivalent on your +platform). + +For languages not fully supported, there will be no project file for the library, just the naked source file(s). +If you successfully use a language, please open an issue or PR to add the missing ones. + +## .NET (C#) + +This is the best supported language. + +F# is not tested. If there are usability or functionality problems, please open an issue. + +Currently, the project file is hard-coded for Linux and will need tweaks for other platforms (e.g. `.dylib` instead of `.so`). + +You do not have to compile or copy the rust crate manually, as building `ServicePoint.csproj` also builds it. + +### Example + +```csharp +using System.Threading; +using ServicePoint; + +var connection = new Connection("127.0.0.1:2342"); +connection.Send(Command.Clear()); + +connection.Send(Command.Brightness(5)); + +var pixels = Bitmap.NewMaxSized(); +for (ulong offset = 0; offset < ulong.MaxValue; offset++) +{ + pixels.Fill(false); + + for (ulong y = 0; y < pixels.Height(); y++) + pixels.Set((y + offset) % pixels.Width(), y, true); + + connection.Send(Command.BitmapLinearWin(0, 0, pixels)); + Thread.Sleep(14); +} +``` + +A full example including project files is available as part of this crate. + +### Why is there no NuGet-Package? + +NuGet packages are not a good way to distribute native +binaries ([relevant issue](https://github.com/dotnet/sdk/issues/33845)). +Because of that, there is no NuGet package you can use directly. diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh index 5b0866d..bfb571c 100755 --- a/crates/servicepoint_binding_uniffi/generate-bindings.sh +++ b/crates/servicepoint_binding_uniffi/generate-bindings.sh @@ -19,6 +19,6 @@ COMMON_ARGS="--library $SERVICEPOINT_SO" ${BINDGEN} generate $COMMON_ARGS --language python --out-dir "$LIBRARIES_PATH/python" ${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir "$LIBRARIES_PATH/kotlin" ${BINDGEN} generate $COMMON_ARGS --language swift --out-dir "$LIBRARIES_PATH/swift" -${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir "$LIBRARIES_PATH/ruby" +${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir "$LIBRARIES_PATH/ruby/lib" ${BINDGEN_CS} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/csharp/ServicePoint" ${BINDGEN_GO} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/go/" diff --git a/crates/servicepoint_binding_uniffi/libraries/.gitignore b/crates/servicepoint_binding_uniffi/libraries/.gitignore new file mode 100644 index 0000000..a875c72 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/.gitignore @@ -0,0 +1,4 @@ +go +kotlin +python +swift \ No newline at end of file diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile new file mode 100644 index 0000000..f44ed21 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'servicepoint', path: '..' diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock new file mode 100644 index 0000000..2b6d5f7 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock @@ -0,0 +1,19 @@ +PATH + remote: .. + specs: + servicepoint (0.0.0) + ffi + +GEM + remote: https://rubygems.org/ + specs: + ffi (1.17.0-x86_64-linux-gnu) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + servicepoint! + +BUNDLED WITH + 2.3.27 diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb new file mode 100644 index 0000000..8d212f2 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb @@ -0,0 +1,25 @@ +require_relative "../lib/servicepoint_binding_uniffi" + +include ServicepointBindingUniffi + +connection = Connection.new("172.23.42.29:2342") + +pixels = Bitmap.new_max_sized +x_offset = 0 +loop do + + pixels.fill(false) + + (0..((pixels.height) -1)).each do |y| + pixels.set((y + x_offset) % pixels.width, y, true); + end + + command = Command.bitmap_linear_win(0, 0, pixels, CompressionCode::UNCOMPRESSED) + + connection.send(command) + sleep 0.0005 + + x_offset += 1 +end + + diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh new file mode 100755 index 0000000..25ed29e --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +LD_LIBRARY_PATH="../../../../../target/release:$LD_LIBRARY_PATH" ruby example.rb diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb b/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb new file mode 100644 index 0000000..b66f128 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb @@ -0,0 +1,1897 @@ +# This file was autogenerated by some hot garbage in the `uniffi` crate. +# Trust me, you don't want to mess with it! + +# Common helper code. +# +# Ideally this would live in a separate .rb file where it can be unittested etc +# in isolation, and perhaps even published as a re-useable package. +# +# However, it's important that the details of how this helper code works (e.g. the +# way that different builtin types are passed across the FFI) exactly match what's +# expected by the rust code on the other side of the interface. In practice right +# now that means coming from the exact some version of `uniffi` that was used to +# compile the rust component. The easiest way to ensure this is to bundle the Ruby +# helpers directly inline like we're doing here. + +require 'ffi' + + +module ServicepointBindingUniffi + def self.uniffi_in_range(i, type_name, min, max) + raise TypeError, "no implicit conversion of #{i} into Integer" unless i.respond_to?(:to_int) + i = i.to_int + raise RangeError, "#{type_name} requires #{min} <= value < #{max}" unless (min <= i && i < max) + i +end + +def self.uniffi_utf8(v) + raise TypeError, "no implicit conversion of #{v} into String" unless v.respond_to?(:to_str) + v = v.to_str.encode(Encoding::UTF_8) + raise Encoding::InvalidByteSequenceError, "not a valid UTF-8 encoded string" unless v.valid_encoding? + v +end + +def self.uniffi_bytes(v) + raise TypeError, "no implicit conversion of #{v} into String" unless v.respond_to?(:to_str) + v.to_str +end + + class RustBuffer < FFI::Struct + layout :capacity, :int32, + :len, :int32, + :data, :pointer + + def self.alloc(size) + return ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_alloc, size) + end + + def self.reserve(rbuf, additional) + return ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_reserve, rbuf, additional) + end + + def free + ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_free, self) + end + + def capacity + self[:capacity] + end + + def len + self[:len] + end + + def len=(value) + self[:len] = value + end + + def data + self[:data] + end + + def to_s + "RustBuffer(capacity=#{capacity}, len=#{len}, data=#{data.read_bytes len})" + end + + # The allocated buffer will be automatically freed if an error occurs, ensuring that + # we don't accidentally leak it. + def self.allocWithBuilder + builder = RustBufferBuilder.new + + begin + yield builder + rescue => e + builder.discard + raise e + end + end + + # The RustBuffer will be freed once the context-manager exits, ensuring that we don't + # leak it even if an error occurs. + def consumeWithStream + stream = RustBufferStream.new self + + yield stream + + raise RuntimeError, 'junk data left in buffer after consuming' if stream.remaining != 0 + ensure + free + end# The primitive String type. + + def self.allocFromString(value) + RustBuffer.allocWithBuilder do |builder| + builder.write value.encode('utf-8') + return builder.finalize + end + end + + def consumeIntoString + consumeWithStream do |stream| + return stream.read(stream.remaining).force_encoding(Encoding::UTF_8) + end + end + + # The primitive Bytes type. + + def self.allocFromBytes(value) + RustBuffer.allocWithBuilder do |builder| + builder.write_Bytes(value) + return builder.finalize + end + end + + def consumeIntoBytes + consumeWithStream do |stream| + return stream.readBytes + end + end + + + + # The Enum type CompressionCode. + + def self.alloc_from_TypeCompressionCode(v) + RustBuffer.allocWithBuilder do |builder| + builder.write_TypeCompressionCode(v) + return builder.finalize + end + end + + def consumeIntoTypeCompressionCode + consumeWithStream do |stream| + return stream.readTypeCompressionCode + end + end + + + + + +end + +module UniFFILib + class ForeignBytes < FFI::Struct + layout :len, :int32, + :data, :pointer + + def len + self[:len] + end + + def data + self[:data] + end + + def to_s + "ForeignBytes(len=#{len}, data=#{data.read_bytes(len)})" + end + end +end + +private_constant :UniFFILib + +# Helper for structured reading of values from a RustBuffer. +class RustBufferStream + + def initialize(rbuf) + @rbuf = rbuf + @offset = 0 + end + + def remaining + @rbuf.len - @offset + end + + def read(size) + raise InternalError, 'read past end of rust buffer' if @offset + size > @rbuf.len + + data = @rbuf.data.get_bytes @offset, size + + @offset += size + + data + end + + def readU8 + unpack_from 1, 'c' + end + + def readU64 + unpack_from 8, 'Q>' + end + + def readBool + v = unpack_from 1, 'c' + + return false if v == 0 + return true if v == 1 + + raise InternalError, 'Unexpected byte for Boolean type' + end + + def readString + size = unpack_from 4, 'l>' + + raise InternalError, 'Unexpected negative string length' if size.negative? + + read(size).force_encoding(Encoding::UTF_8) + end + + def readBytes + size = unpack_from 4, 'l>' + + raise InternalError, 'Unexpected negative byte string length' if size.negative? + + read(size).force_encoding(Encoding::BINARY) + end + + # The Object type BitVec. + + def readTypeBitVec + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return BitVec._uniffi_allocate(pointer) + end + + # The Object type Bitmap. + + def readTypeBitmap + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return Bitmap._uniffi_allocate(pointer) + end + + # The Object type BrightnessGrid. + + def readTypeBrightnessGrid + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return BrightnessGrid._uniffi_allocate(pointer) + end + + # The Object type CharGrid. + + def readTypeCharGrid + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return CharGrid._uniffi_allocate(pointer) + end + + # The Object type Command. + + def readTypeCommand + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return Command._uniffi_allocate(pointer) + end + + # The Object type Connection. + + def readTypeConnection + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return Connection._uniffi_allocate(pointer) + end + + # The Object type Cp437Grid. + + def readTypeCp437Grid + pointer = FFI::Pointer.new unpack_from 8, 'Q>' + return Cp437Grid._uniffi_allocate(pointer) + end + + + + + + # The Error type CharGridError + + def readTypeCharGridError + variant = unpack_from 4, 'l>' + + if variant == 1 + return CharGridError::StringNotOneChar.new( + readString() + ) + end + if variant == 2 + return CharGridError::InvalidSeriesLength.new( + readU64(), + readU64() + ) + end + if variant == 3 + return CharGridError::OutOfBounds.new( + readU64(), + readU64() + ) + end + + raise InternalError, 'Unexpected variant tag for TypeCharGridError' + end + + + + + # The Enum type CompressionCode. + + def readTypeCompressionCode + variant = unpack_from 4, 'l>' + + if variant == 1 + return CompressionCode::UNCOMPRESSED + end + if variant == 2 + return CompressionCode::ZLIB + end + if variant == 3 + return CompressionCode::BZIP2 + end + if variant == 4 + return CompressionCode::LZMA + end + if variant == 5 + return CompressionCode::ZSTD + end + + raise InternalError, 'Unexpected variant tag for TypeCompressionCode' + end + + + + + + + + # The Error type ServicePointError + + def readTypeServicePointError + variant = unpack_from 4, 'l>' + + if variant == 1 + return ServicePointError::IoError.new( + readString() + ) + end + if variant == 2 + return ServicePointError::InvalidBrightness.new( + readU8() + ) + end + + raise InternalError, 'Unexpected variant tag for TypeServicePointError' + end + + + + + def unpack_from(size, format) + raise InternalError, 'read past end of rust buffer' if @offset + size > @rbuf.len + + value = @rbuf.data.get_bytes(@offset, size).unpack format + + @offset += size + + # TODO: verify this + raise 'more than one element!!!' if value.size > 1 + + value[0] + end +end + +private_constant :RustBufferStream + +# Helper for structured writing of values into a RustBuffer. +class RustBufferBuilder + def initialize + @rust_buf = RustBuffer.alloc 16 + @rust_buf.len = 0 + end + + def finalize + rbuf = @rust_buf + + @rust_buf = nil + + rbuf + end + + def discard + return if @rust_buf.nil? + + rbuf = finalize + rbuf.free + end + + def write(value) + reserve(value.bytes.size) do + @rust_buf.data.put_array_of_char @rust_buf.len, value.bytes + end + end + + def write_U8(v) + v = ServicepointBindingUniffi::uniffi_in_range(v, "u8", 0, 2**8) + pack_into(1, 'c', v) + end + + def write_U64(v) + v = ServicepointBindingUniffi::uniffi_in_range(v, "u64", 0, 2**64) + pack_into(8, 'Q>', v) + end + + def write_Bool(v) + pack_into(1, 'c', v ? 1 : 0) + end + + def write_String(v) + v = ServicepointBindingUniffi::uniffi_utf8(v) + pack_into 4, 'l>', v.bytes.size + write v + end + + def write_Bytes(v) + v = ServicepointBindingUniffi::uniffi_bytes(v) + pack_into 4, 'l>', v.bytes.size + write v + end + + # The Object type BitVec. + + def write_TypeBitVec(obj) + pointer = BitVec._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type Bitmap. + + def write_TypeBitmap(obj) + pointer = Bitmap._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type BrightnessGrid. + + def write_TypeBrightnessGrid(obj) + pointer = BrightnessGrid._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type CharGrid. + + def write_TypeCharGrid(obj) + pointer = CharGrid._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type Command. + + def write_TypeCommand(obj) + pointer = Command._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type Connection. + + def write_TypeConnection(obj) + pointer = Connection._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + # The Object type Cp437Grid. + + def write_TypeCp437Grid(obj) + pointer = Cp437Grid._uniffi_lower obj + pack_into(8, 'Q>', pointer.address) + end + + + + # The Enum type CompressionCode. + + def write_TypeCompressionCode(v) + pack_into(4, 'l>', v) + end + + + + + + + private + + def reserve(num_bytes) + if @rust_buf.len + num_bytes > @rust_buf.capacity + @rust_buf = RustBuffer.reserve(@rust_buf, num_bytes) + end + + yield + + @rust_buf.len += num_bytes + end + + def pack_into(size, format, value) + reserve(size) do + @rust_buf.data.put_array_of_char @rust_buf.len, [value].pack(format).bytes + end + end +end + +private_constant :RustBufferBuilder + + # Error definitions + class RustCallStatus < FFI::Struct + layout :code, :int8, + :error_buf, RustBuffer + + def code + self[:code] + end + + def error_buf + self[:error_buf] + end + + def to_s + "RustCallStatus(code=#{self[:code]})" + end +end + +# These match the values from the uniffi::rustcalls module +CALL_SUCCESS = 0 +CALL_ERROR = 1 +CALL_PANIC = 2 + + +module CharGridError + class StringNotOneChar < StandardError + def initialize(value) + @value = value + super() + end + + attr_reader :value + + + def to_s + "#{self.class.name}(value=#{@value.inspect})" + end + end + class InvalidSeriesLength < StandardError + def initialize(actual, expected) + @actual = actual + @expected = expected + super() + end + + attr_reader :actual, :expected + + + def to_s + "#{self.class.name}(actual=#{@actual.inspect}, expected=#{@expected.inspect})" + end + end + class OutOfBounds < StandardError + def initialize(index, size) + @index = index + @size = size + super() + end + + attr_reader :index, :size + + + def to_s + "#{self.class.name}(index=#{@index.inspect}, size=#{@size.inspect})" + end + end + +end + + + + +module ServicePointError + class IoError < StandardError + def initialize(error) + @error = error + super() + end + + attr_reader :error + + + def to_s + "#{self.class.name}(error=#{@error.inspect})" + end + end + class InvalidBrightness < StandardError + def initialize(value) + @value = value + super() + end + + attr_reader :value + + + def to_s + "#{self.class.name}(value=#{@value.inspect})" + end + end + +end + + +# Map error modules to the RustBuffer method name that reads them +ERROR_MODULE_TO_READER_METHOD = { + + CharGridError => :readTypeCharGridError, + + + + ServicePointError => :readTypeServicePointError, + +} + +private_constant :ERROR_MODULE_TO_READER_METHOD, :CALL_SUCCESS, :CALL_ERROR, :CALL_PANIC, + :RustCallStatus + +def self.consume_buffer_into_error(error_module, rust_buffer) + rust_buffer.consumeWithStream do |stream| + reader_method = ERROR_MODULE_TO_READER_METHOD[error_module] + return stream.send(reader_method) + end +end + +class InternalError < StandardError +end + +def self.rust_call(fn_name, *args) + # Call a rust function + rust_call_with_error(nil, fn_name, *args) +end + +def self.rust_call_with_error(error_module, fn_name, *args) + # Call a rust function and handle errors + # + # Use this when the rust function returns a Result<>. error_module must be the error_module that corresponds to that Result. + + + # Note: RustCallStatus.new zeroes out the struct, which is exactly what we + # want to pass to Rust (code=0, error_buf=RustBuffer(len=0, capacity=0, + # data=NULL)) + status = RustCallStatus.new + args << status + + result = UniFFILib.public_send(fn_name, *args) + + case status.code + when CALL_SUCCESS + result + when CALL_ERROR + if error_module.nil? + status.error_buf.free + raise InternalError, "CALL_ERROR with no error_module set" + else + raise consume_buffer_into_error(error_module, status.error_buf) + end + when CALL_PANIC + # When the rust code sees a panic, it tries to construct a RustBuffer + # with the message. But if that code panics, then it just sends back + # an empty buffer. + if status.error_buf.len > 0 + raise InternalError, status.error_buf.consumeIntoString() + else + raise InternalError, "Rust panic" + end + else + raise InternalError, "Unknown call status: #{status.code}" + end +end + +private_class_method :consume_buffer_into_error + + # This is how we find and load the dynamic library provided by the component. +# For now we just look it up by name. +module UniFFILib + extend FFI::Library + + + ffi_lib 'servicepoint_binding_uniffi' + + + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_bitvec, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load, + [RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new, + [:uint64, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw, + [:pointer, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill, + [:pointer, :int8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get, + [:pointer, :uint64, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set, + [:pointer, :uint64, :int8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_bitmap, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load, + [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new, + [:uint64, :uint64, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized, + [RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw, + [:pointer, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill, + [:pointer, :int8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get, + [:pointer, :uint64, :uint64, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set, + [:pointer, :uint64, :uint64, :int8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load, + [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new, + [:uint64, :uint64, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw, + [:pointer, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill, + [:pointer, :uint8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get, + [:pointer, :uint64, :uint64, RustCallStatus.by_ref], + :uint8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set, + [:pointer, :uint64, :uint64, :uint8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_chargrid, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load, + [RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new, + [:uint64, :uint64, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string, + [:pointer, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill, + [:pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get, + [:pointer, :uint64, :uint64, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col, + [:pointer, :uint64, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row, + [:pointer, :uint64, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set, + [:pointer, :uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col, + [:pointer, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row, + [:pointer, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_command, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear, + [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and, + [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or, + [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win, + [:uint64, :uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor, + [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness, + [:uint8, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness, + [:uint64, :uint64, :pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear, + [RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data, + [:uint64, :uint64, :pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out, + [RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset, + [RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_command_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_connection, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new, + [RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake, + [RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_connection_send, + [:pointer, :pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_free_cp437grid, + [:pointer, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load, + [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new, + [:uint64, :uint64, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw, + [:pointer, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals, + [:pointer, :pointer, RustCallStatus.by_ref], + :int8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill, + [:pointer, :uint8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get, + [:pointer, :uint64, :uint64, RustCallStatus.by_ref], + :uint8 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set, + [:pointer, :uint64, :uint64, :uint8, RustCallStatus.by_ref], + :void + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8, + [:pointer, RustCallStatus.by_ref], + :pointer + attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width, + [:pointer, RustCallStatus.by_ref], + :uint64 + attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_alloc, + [:int32, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_from_bytes, + [ForeignBytes, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_free, + [RustBuffer.by_value, RustCallStatus.by_ref], + :void + attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_reserve, + [RustBuffer.by_value, :int32, RustCallStatus.by_ref], + RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_copy_raw, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_get, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_height, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_set, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_copy_raw, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_get, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_height, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_set, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_as_string, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_fill, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_col, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_row, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_height, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_col, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_row, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_to_cp437, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_width, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_command_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_connection_send, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_copy_raw, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_equals, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_fill, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_get, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_height, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_to_utf8, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_load, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_char_brightness, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_cp437_data, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_hard_reset, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_clone, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_load, + [RustCallStatus.by_ref], + :uint16 + attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_new, + [RustCallStatus.by_ref], + :uint16 + attach_function :ffi_servicepoint_binding_uniffi_uniffi_contract_version, + [RustCallStatus.by_ref], + :uint32 + +end + + # Public interface members begin here. + + + + + + +class CompressionCode + UNCOMPRESSED = 1 + ZLIB = 2 + BZIP2 = 3 + LZMA = 4 + ZSTD = 5 + +end + + + + + + + + + class BitVec + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_bitvec, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a BitVec instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(size) + size = ServicepointBindingUniffi::uniffi_in_range(size, "u64", 0, 2**64) + pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new,size) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone,(BitVec._uniffi_lower other))) + end + def self.load(data) + data = ServicepointBindingUniffi::uniffi_bytes(data) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load,RustBuffer.allocFromBytes(data))) + end + + + def copy_raw() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw,@pointer,) + return result.consumeIntoBytes + end + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals,@pointer,(BitVec._uniffi_lower other)) + return 1 == result + end + def fill(value) + value = value ? true : false + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill,@pointer,(value ? 1 : 0)) + end + + def get(index) + index = ServicepointBindingUniffi::uniffi_in_range(index, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get,@pointer,index) + return 1 == result + end + def len() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len,@pointer,) + return result.to_i + end + def set(index, value) + index = ServicepointBindingUniffi::uniffi_in_range(index, "u64", 0, 2**64) + value = value ? true : false + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set,@pointer,index,(value ? 1 : 0)) + end + + +end + + class Bitmap + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_bitmap, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a Bitmap instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(width, height) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new,width,height) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone,(Bitmap._uniffi_lower other))) + end + def self.load(width, height, data) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + data = ServicepointBindingUniffi::uniffi_bytes(data) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load,width,height,RustBuffer.allocFromBytes(data))) + end + def self.new_max_sized() + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized,)) + end + + + def copy_raw() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw,@pointer,) + return result.consumeIntoBytes + end + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals,@pointer,(Bitmap._uniffi_lower other)) + return 1 == result + end + def fill(value) + value = value ? true : false + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill,@pointer,(value ? 1 : 0)) + end + + def get(x, y) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get,@pointer,x,y) + return 1 == result + end + def height() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height,@pointer,) + return result.to_i + end + def set(x, y, value) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + value = value ? true : false + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set,@pointer,x,y,(value ? 1 : 0)) + end + + def width() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width,@pointer,) + return result.to_i + end + +end + + class BrightnessGrid + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a BrightnessGrid instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(width, height) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new,width,height) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone,(BrightnessGrid._uniffi_lower other))) + end + def self.load(width, height, data) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + data = ServicepointBindingUniffi::uniffi_bytes(data) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load,width,height,RustBuffer.allocFromBytes(data))) + end + + + def copy_raw() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw,@pointer,) + return result.consumeIntoBytes + end + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals,@pointer,(BrightnessGrid._uniffi_lower other)) + return 1 == result + end + def fill(value) + value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8) + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill,@pointer,value) + end + + def get(x, y) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get,@pointer,x,y) + return result.to_i + end + def height() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height,@pointer,) + return result.to_i + end + def set(x, y, value) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8) + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set,@pointer,x,y,value) + end + + def width() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width,@pointer,) + return result.to_i + end + +end + + class CharGrid + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_chargrid, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a CharGrid instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(width, height) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new,width,height) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone,(CharGrid._uniffi_lower other))) + end + def self.load(data) + data = ServicepointBindingUniffi::uniffi_utf8(data) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load,RustBuffer.allocFromString(data))) + end + + + def as_string() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string,@pointer,) + return result.consumeIntoString + end + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals,@pointer,(CharGrid._uniffi_lower other)) + return 1 == result + end + def fill(value) + value = ServicepointBindingUniffi::uniffi_utf8(value) + ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill,@pointer,RustBuffer.allocFromString(value)) + end + + def get(x, y) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get,@pointer,x,y) + return result.consumeIntoString + end + def get_col(x) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col,@pointer,x) + return result.consumeIntoString + end + def get_row(y) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row,@pointer,y) + return result.consumeIntoString + end + def height() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height,@pointer,) + return result.to_i + end + def set(x, y, value) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + value = ServicepointBindingUniffi::uniffi_utf8(value) + ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set,@pointer,x,y,RustBuffer.allocFromString(value)) + end + + def set_col(x, col) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + col = ServicepointBindingUniffi::uniffi_utf8(col) + ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col,@pointer,x,RustBuffer.allocFromString(col)) + end + + def set_row(y, row) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + row = ServicepointBindingUniffi::uniffi_utf8(row) + ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row,@pointer,y,RustBuffer.allocFromString(row)) + end + + def to_cp437() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437,@pointer,) + return Cp437Grid._uniffi_allocate(result) + end + def width() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width,@pointer,) + return result.to_i + end + +end + + class Command + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_command, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a Command instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + + def self.bitmap_linear(offset, bitmap, compression) + offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64) + bitmap = bitmap + compression = compression + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression))) + end + def self.bitmap_linear_and(offset, bitmap, compression) + offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64) + bitmap = bitmap + compression = compression + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression))) + end + def self.bitmap_linear_or(offset, bitmap, compression) + offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64) + bitmap = bitmap + compression = compression + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression))) + end + def self.bitmap_linear_win(offset_x, offset_y, bitmap, compression) + offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64) + offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64) + bitmap = bitmap + compression = compression + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win,offset_x,offset_y,(Bitmap._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression))) + end + def self.bitmap_linear_xor(offset, bitmap, compression) + offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64) + bitmap = bitmap + compression = compression + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression))) + end + def self.brightness(brightness) + brightness = ServicepointBindingUniffi::uniffi_in_range(brightness, "u8", 0, 2**8) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness,brightness)) + end + def self.char_brightness(offset_x, offset_y, grid) + offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64) + offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64) + grid = grid + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness,offset_x,offset_y,(BrightnessGrid._uniffi_lower grid))) + end + def self.clear() + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear,)) + end + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone,(Command._uniffi_lower other))) + end + def self.cp437_data(offset_x, offset_y, grid) + offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64) + offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64) + grid = grid + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data,offset_x,offset_y,(Cp437Grid._uniffi_lower grid))) + end + def self.fade_out() + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out,)) + end + def self.hard_reset() + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset,)) + end + + + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_command_equals,@pointer,(Command._uniffi_lower other)) + return 1 == result + end + +end + + class Connection + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_connection, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a Connection instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(host) + host = ServicepointBindingUniffi::uniffi_utf8(host) + pointer = ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new,RustBuffer.allocFromString(host)) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.new_fake() + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake,)) + end + + + def send(command) + command = command + ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_method_connection_send,@pointer,(Command._uniffi_lower command)) + end + + +end + + class Cp437Grid + + # A private helper for initializing instances of the class from a raw pointer, + # bypassing any initialization logic and ensuring they are GC'd properly. + def self._uniffi_allocate(pointer) + pointer.autorelease = false + inst = allocate + inst.instance_variable_set :@pointer, pointer + ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id)) + return inst + end + + # A private helper for registering an object finalizer. + # N.B. it's important that this does not capture a reference + # to the actual instance, only its underlying pointer. + def self._uniffi_define_finalizer_by_pointer(pointer, object_id) + Proc.new do |_id| + ServicepointBindingUniffi.rust_call( + :uniffi_servicepoint_binding_uniffi_fn_free_cp437grid, + pointer + ) + end + end + + # A private helper for lowering instances into a raw pointer. + # This does an explicit typecheck, because accidentally lowering a different type of + # object in a place where this type is expected, could lead to memory unsafety. + def self._uniffi_lower(inst) + if not inst.is_a? self + raise TypeError.new "Expected a Cp437Grid instance, got #{inst}" + end + return inst.instance_variable_get :@pointer + end + def initialize(width, height) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new,width,height) + @pointer = pointer + ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id)) + end + + def self.clone(other) + other = other + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone,(Cp437Grid._uniffi_lower other))) + end + def self.load(width, height, data) + width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64) + height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64) + data = ServicepointBindingUniffi::uniffi_bytes(data) + # Call the (fallible) function before creating any half-baked object instances. + # Lightly yucky way to bypass the usual "initialize" logic + # and just create a new instance with the required pointer. + return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load,width,height,RustBuffer.allocFromBytes(data))) + end + + + def copy_raw() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw,@pointer,) + return result.consumeIntoBytes + end + def equals(other) + other = other + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals,@pointer,(Cp437Grid._uniffi_lower other)) + return 1 == result + end + def fill(value) + value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8) + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill,@pointer,value) + end + + def get(x, y) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get,@pointer,x,y) + return result.to_i + end + def height() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height,@pointer,) + return result.to_i + end + def set(x, y, value) + x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64) + y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64) + value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8) + ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set,@pointer,x,y,value) + end + + def to_utf8() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8,@pointer,) + return CharGrid._uniffi_allocate(result) + end + def width() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width,@pointer,) + return result.to_i + end + +end + +end + diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec b/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec new file mode 100644 index 0000000..412482f --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec @@ -0,0 +1,13 @@ +Gem::Specification.new do |s| + s.name = "servicepoint" + s.version = "0.0.0" + s.summary = "" + s.description = "" + s.authors = ["kaesaecracker"] + s.email = "" + s.files = ["lib/servicepoint_binding_uniffi.rb"] + s.homepage = + "https://rubygems.org/gems/hola" + s.license = "MIT" + s.add_dependency 'ffi' +end diff --git a/flake.nix b/flake.nix index 0d70b7c..5ead28d 100644 --- a/flake.nix +++ b/flake.nix @@ -69,10 +69,10 @@ strictDeps = true; buildInputs = buildInputs; overrideMain = old: { - preConfigure = '' - cargo_build_options="$cargo_build_options --example ${example}" - ''; - }; + preConfigure = '' + cargo_build_options="$cargo_build_options --example ${example}" + ''; + }; }; makePackage = package: @@ -117,16 +117,19 @@ clippy cargo-expand cargo-tarpaulin - gcc - gnumake - dotnet-sdk_8 ]; }; in { default = pkgs.mkShell rec { inputsFrom = [ self.packages.${system}.servicepoint ]; - packages = [ rust-toolchain ]; + packages = with pkgs; [ + rust-toolchain + ruby + dotnet-sdk_8 + gcc + gnumake + ]; LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath (builtins.concatMap (d: d.buildInputs) inputsFrom)}"; RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; }; From 666a0e6c01a33dd60cc022a25c0ca47e84949234 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 19:53:38 +0100 Subject: [PATCH 14/18] add constants --- .../servicepoint_binding_uniffi.cs | 67 ++++++++++++++ .../ruby/lib/servicepoint_binding_uniffi.rb | 91 +++++++++++++++++++ .../src/constants.rs | 21 +++++ crates/servicepoint_binding_uniffi/src/lib.rs | 1 + 4 files changed, 180 insertions(+) create mode 100644 crates/servicepoint_binding_uniffi/src/constants.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index f9a6975..a9077dd 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -751,6 +751,10 @@ static class _UniFFILib { public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width(Cp437GridSafeHandle @ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern RustBuffer uniffi_servicepoint_binding_uniffi_fn_func_get_constants(ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern RustBuffer ffi_servicepoint_binding_uniffi_rustbuffer_alloc(int @size,ref RustCallStatus _uniffi_out_err ); @@ -979,6 +983,10 @@ static class _UniFFILib { public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_func_get_constants( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw( ); @@ -1281,6 +1289,12 @@ static class _UniFFILib { } static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_func_get_constants(); + if (checksum != 41584) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_func_get_constants` checksum `41584`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw(); if (checksum != 12617) { @@ -2902,6 +2916,52 @@ class FfiConverterTypeCp437Grid: FfiConverter { +public record Constants ( + ulong @tileSize, + ulong @tileWidth, + ulong @tileHeight, + ulong @pixelWidth, + ulong @pixelHeight, + ulong @pixelCount +) { +} + +class FfiConverterTypeConstants: FfiConverterRustBuffer { + public static FfiConverterTypeConstants INSTANCE = new FfiConverterTypeConstants(); + + public override Constants Read(BigEndianStream stream) { + return new Constants( + @tileSize: FfiConverterUInt64.INSTANCE.Read(stream), + @tileWidth: FfiConverterUInt64.INSTANCE.Read(stream), + @tileHeight: FfiConverterUInt64.INSTANCE.Read(stream), + @pixelWidth: FfiConverterUInt64.INSTANCE.Read(stream), + @pixelHeight: FfiConverterUInt64.INSTANCE.Read(stream), + @pixelCount: FfiConverterUInt64.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(Constants value) { + return + FfiConverterUInt64.INSTANCE.AllocationSize(value.@tileSize) + + FfiConverterUInt64.INSTANCE.AllocationSize(value.@tileWidth) + + FfiConverterUInt64.INSTANCE.AllocationSize(value.@tileHeight) + + FfiConverterUInt64.INSTANCE.AllocationSize(value.@pixelWidth) + + FfiConverterUInt64.INSTANCE.AllocationSize(value.@pixelHeight) + + FfiConverterUInt64.INSTANCE.AllocationSize(value.@pixelCount); + } + + public override void Write(Constants value, BigEndianStream stream) { + FfiConverterUInt64.INSTANCE.Write(value.@tileSize, stream); + FfiConverterUInt64.INSTANCE.Write(value.@tileWidth, stream); + FfiConverterUInt64.INSTANCE.Write(value.@tileHeight, stream); + FfiConverterUInt64.INSTANCE.Write(value.@pixelWidth, stream); + FfiConverterUInt64.INSTANCE.Write(value.@pixelHeight, stream); + FfiConverterUInt64.INSTANCE.Write(value.@pixelCount, stream); + } +} + + + public class CharGridException: UniffiException { @@ -3133,5 +3193,12 @@ class FfiConverterTypeServicePointException : FfiConverterRustBuffer + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_func_get_constants( ref _status) +)); + } + } diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb b/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb index b66f128..1e7aac7 100644 --- a/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb @@ -126,6 +126,21 @@ end end end + # The Record type Constants. + + def self.alloc_from_TypeConstants(v) + RustBuffer.allocWithBuilder do |builder| + builder.write_TypeConstants(v) + return builder.finalize + end + end + + def consumeIntoTypeConstants + consumeWithStream do |stream| + return stream.readTypeConstants + end + end + # The Enum type CompressionCode. @@ -274,6 +289,19 @@ class RustBufferStream return Cp437Grid._uniffi_allocate(pointer) end + # The Record type Constants. + + def readTypeConstants + Constants.new( + readU64, + readU64, + readU64, + readU64, + readU64, + readU64 + ) + end + @@ -478,6 +506,17 @@ class RustBufferBuilder pack_into(8, 'Q>', pointer.address) end + # The Record type Constants. + + def write_TypeConstants(v) + self.write_U64(v.tile_size) + self.write_U64(v.tile_width) + self.write_U64(v.tile_height) + self.write_U64(v.pixel_width) + self.write_U64(v.pixel_height) + self.write_U64(v.pixel_count) + end + # The Enum type CompressionCode. @@ -930,6 +969,9 @@ module UniFFILib attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width, [:pointer, RustCallStatus.by_ref], :uint64 + attach_function :uniffi_servicepoint_binding_uniffi_fn_func_get_constants, + [RustCallStatus.by_ref], + RustBuffer.by_value attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_alloc, [:int32, RustCallStatus.by_ref], RustBuffer.by_value @@ -942,6 +984,9 @@ module UniFFILib attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_reserve, [RustBuffer.by_value, :int32, RustCallStatus.by_ref], RustBuffer.by_value + attach_function :uniffi_servicepoint_binding_uniffi_checksum_func_get_constants, + [RustCallStatus.by_ref], + :uint16 attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw, [RustCallStatus.by_ref], :uint16 @@ -1183,6 +1228,52 @@ end + # Record type Constants +class Constants + attr_reader :tile_size, :tile_width, :tile_height, :pixel_width, :pixel_height, :pixel_count + + def initialize(tile_size, tile_width, tile_height, pixel_width, pixel_height, pixel_count) + @tile_size = tile_size + @tile_width = tile_width + @tile_height = tile_height + @pixel_width = pixel_width + @pixel_height = pixel_height + @pixel_count = pixel_count + end + + def ==(other) + if @tile_size != other.tile_size + return false + end + if @tile_width != other.tile_width + return false + end + if @tile_height != other.tile_height + return false + end + if @pixel_width != other.pixel_width + return false + end + if @pixel_height != other.pixel_height + return false + end + if @pixel_count != other.pixel_count + return false + end + + true + end +end + + + + + +def self.get_constants() + result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_func_get_constants,) + return result.consumeIntoTypeConstants +end + diff --git a/crates/servicepoint_binding_uniffi/src/constants.rs b/crates/servicepoint_binding_uniffi/src/constants.rs new file mode 100644 index 0000000..be89a9c --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/constants.rs @@ -0,0 +1,21 @@ +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, uniffi::Record)] +pub struct Constants { + pub tile_size: u64, + pub tile_width: u64, + pub tile_height: u64, + pub pixel_width: u64, + pub pixel_height: u64, + pub pixel_count: u64, +} + +#[uniffi::export] +fn get_constants() -> Constants { +Constants { + tile_size: servicepoint::TILE_SIZE as u64, + tile_width: servicepoint::TILE_WIDTH as u64, + tile_height: servicepoint::TILE_HEIGHT as u64, + pixel_width: servicepoint::PIXEL_WIDTH as u64, + pixel_height: servicepoint::PIXEL_HEIGHT as u64, + pixel_count: servicepoint::PIXEL_COUNT as u64, + } +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 29564aa..1c932e6 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -9,3 +9,4 @@ mod compression_code; mod connection; mod cp437_grid; mod errors; +mod constants; From d5c4c61083cbd2cf7c9d2cfc477c5221d039b61a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 19:55:35 +0100 Subject: [PATCH 15/18] clippy fixes --- crates/servicepoint_binding_uniffi/src/char_grid.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/servicepoint_binding_uniffi/src/char_grid.rs b/crates/servicepoint_binding_uniffi/src/char_grid.rs index 9dafce4..bd9e1b8 100644 --- a/crates/servicepoint_binding_uniffi/src/char_grid.rs +++ b/crates/servicepoint_binding_uniffi/src/char_grid.rs @@ -89,7 +89,7 @@ impl CharGrid { self.actual .write() .unwrap() - .set_row(y as usize, &*row.chars().collect::>()) + .set_row(y as usize, &row.chars().collect::>()) .map_err(CharGridError::from) } @@ -97,7 +97,7 @@ impl CharGrid { self.actual .write() .unwrap() - .set_row(x as usize, &*col.chars().collect::>()) + .set_row(x as usize, &col.chars().collect::>()) .map_err(CharGridError::from) } @@ -106,7 +106,7 @@ impl CharGrid { .read() .unwrap() .get_row(y as usize) - .map(move |vec| String::from_iter(vec)) + .map(String::from_iter) .ok_or(CharGridError::OutOfBounds {index: y, size: self.height()}) } @@ -115,7 +115,7 @@ impl CharGrid { .read() .unwrap() .get_col(x as usize) - .map(move |vec| String::from_iter(vec)) + .map(String::from_iter) .ok_or(CharGridError::OutOfBounds {index: x, size: self.width()}) } From e0249b61b8caf64bb8b8b9d0a38304144520e167 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 20:15:02 +0100 Subject: [PATCH 16/18] add singleton object for constants in c# --- .../libraries/csharp/ServicePoint/Constants.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/Constants.cs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/Constants.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/Constants.cs new file mode 100644 index 0000000..58cf560 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/Constants.cs @@ -0,0 +1,14 @@ + +using ServicePoint; + +public static class ServicePointConstants +{ + private static readonly Constants _instance = ServicepointBindingUniffiMethods.GetConstants(); + + public static readonly ulong PixelWidth = _instance.pixelWidth; + public static readonly ulong PixelHeight = _instance.pixelHeight; + public static readonly ulong PixelCount = _instance.pixelCount; + public static readonly ulong TileWidth = _instance.tileWidth; + public static readonly ulong TileHeight = _instance.tileHeight; + public static readonly ulong TileSize = _instance.tileSize; +} From 843f5a03a670a0c65c7d281f3dfdd5585d85b025 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 21:20:06 +0100 Subject: [PATCH 17/18] version 0.12.0 --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- crates/servicepoint/README.md | 2 +- crates/servicepoint_binding_c/Cargo.toml | 2 +- crates/servicepoint_binding_uniffi/Cargo.toml | 4 ++-- .../libraries/csharp/ServicePoint/ServicePoint.csproj | 2 +- .../libraries/ruby/servicepoint.gemspec | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3819516..69d32db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -931,7 +931,7 @@ dependencies = [ [[package]] name = "servicepoint" -version = "0.11.0" +version = "0.12.0" dependencies = [ "bitvec", "bzip2", @@ -948,7 +948,7 @@ dependencies = [ [[package]] name = "servicepoint_binding_c" -version = "0.11.0" +version = "0.12.0" dependencies = [ "cbindgen", "servicepoint", @@ -956,7 +956,7 @@ dependencies = [ [[package]] name = "servicepoint_binding_uniffi" -version = "0.11.0" +version = "0.12.0" dependencies = [ "servicepoint", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 9eae2e7..20457c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,10 @@ members = [ ] [workspace.package] -version = "0.11.0" +version = "0.12.0" [workspace.lints.rust] missing-docs = "warn" [workspace.dependencies] -thiserror = "1.0.69" \ No newline at end of file +thiserror = "1.0.69" diff --git a/crates/servicepoint/README.md b/crates/servicepoint/README.md index 0a1064f..e4bae8a 100644 --- a/crates/servicepoint/README.md +++ b/crates/servicepoint/README.md @@ -17,7 +17,7 @@ cargo add servicepoint or ```toml [dependencies] -servicepoint = "0.11.0" +servicepoint = "0.12.0" ``` ## Examples diff --git a/crates/servicepoint_binding_c/Cargo.toml b/crates/servicepoint_binding_c/Cargo.toml index 91122d3..0a4d2d5 100644 --- a/crates/servicepoint_binding_c/Cargo.toml +++ b/crates/servicepoint_binding_c/Cargo.toml @@ -17,7 +17,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] cbindgen = "0.27.0" [dependencies.servicepoint] -version = "0.11.0" +version = "0.12.0" path = "../servicepoint" features = ["all_compressions"] diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml index 3b02bd2..c5c901a 100644 --- a/crates/servicepoint_binding_uniffi/Cargo.toml +++ b/crates/servicepoint_binding_uniffi/Cargo.toml @@ -20,7 +20,7 @@ uniffi = { version = "0.25.3" } thiserror.workspace = true [dependencies.servicepoint] -version = "0.11.0" +version = "0.12.0" path = "../servicepoint" features = ["all_compressions"] @@ -57,4 +57,4 @@ required-features = ["go"] [features] default = [] cs = ["dep:uniffi-bindgen-cs"] -go = ["dep:uniffi-bindgen-go"] \ No newline at end of file +go = ["dep:uniffi-bindgen-go"] diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj index 5b7dc28..135a26f 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/ServicePoint.csproj @@ -9,7 +9,7 @@ ServicePoint - 0.10.0 + 0.12.0 Repository Authors None ServicePoint diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec b/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec index 412482f..477a9ff 100644 --- a/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec +++ b/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "servicepoint" - s.version = "0.0.0" + s.version = "0.12.0" s.summary = "" s.description = "" s.authors = ["kaesaecracker"] From 0fe885e231d8c77a0c3cc9475bf6193973d2e41d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 23 Nov 2024 22:57:10 +0100 Subject: [PATCH 18/18] fix examples in flake --- flake.nix | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/flake.nix b/flake.nix index 5ead28d..e373fd2 100644 --- a/flake.nix +++ b/flake.nix @@ -54,7 +54,11 @@ lzma ]; makeExample = - package: example: + { + package, + example, + features ? "", + }: naersk'.buildPackage { pname = example; cargoBuildOptions = @@ -68,9 +72,12 @@ nativeBuildInputs = nativeBuildInputs; strictDeps = true; buildInputs = buildInputs; + gitSubmodules = true; overrideMain = old: { preConfigure = '' - cargo_build_options="$cargo_build_options --example ${example}" + cargo_build_options="$cargo_build_options --example ${example} ${ + if features == "" then "" else "--features " + features + }" ''; }; }; @@ -95,11 +102,28 @@ in rec { servicepoint = makePackage "servicepoint"; - announce = makeExample "servicepoint" "announce"; - game-of-life = makeExample "servicepoint" "game_of_life"; - moving-line = makeExample "servicepoint" "moving_line"; - random-brightness = makeExample "servicepoint" "random_brightness"; - wiping-clear = makeExample "servicepoint" "wiping_clear"; + announce = makeExample { + package = "servicepoint"; + example = "announce"; + }; + game-of-life = makeExample { + package = "servicepoint"; + example = "game_of_life"; + features = "rand"; + }; + moving-line = makeExample { + package = "servicepoint"; + example = "moving_line"; + }; + random-brightness = makeExample { + package = "servicepoint"; + example = "random_brightness"; + features = "rand"; + }; + wiping-clear = makeExample { + package = "servicepoint"; + example = "wiping_clear"; + }; } );