WIP: update servicepoint library #1
					 29 changed files with 866 additions and 721 deletions
				
			
		
							
								
								
									
										95
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										95
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| # This file is automatically @generated by Cargo. | ||||
| # It is not intended for manual editing. | ||||
| version = 3 | ||||
| version = 4 | ||||
| 
 | ||||
| [[package]] | ||||
| name = "adler2" | ||||
|  | @ -209,9 +209,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" | |||
| 
 | ||||
| [[package]] | ||||
| name = "goblin" | ||||
| version = "0.6.1" | ||||
| version = "0.8.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" | ||||
| checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" | ||||
| dependencies = [ | ||||
|  "log", | ||||
|  "plain", | ||||
|  | @ -220,9 +220,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "heck" | ||||
| version = "0.4.1" | ||||
| version = "0.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" | ||||
| checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "itoa" | ||||
|  | @ -304,12 +304,6 @@ 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 = "paste" | ||||
| version = "1.0.15" | ||||
|  | @ -370,18 +364,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" | |||
| 
 | ||||
| [[package]] | ||||
| name = "scroll" | ||||
| version = "0.11.0" | ||||
| version = "0.12.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" | ||||
| checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" | ||||
| dependencies = [ | ||||
|  "scroll_derive", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "scroll_derive" | ||||
| version = "0.11.1" | ||||
| version = "0.12.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" | ||||
| checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -431,9 +425,8 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "servicepoint" | ||||
| version = "0.13.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "93b52049be55a15fe37c13249d7f96aa8a5de56e1a41838e74a822ee8316a0c4" | ||||
| version = "0.15.0" | ||||
| source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint.git?branch=next#5b6f88b1682925b7669b25a7fb08806c4009bbfd" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "bzip2", | ||||
|  | @ -447,8 +440,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "servicepoint_binding_uniffi" | ||||
| version = "0.13.1" | ||||
| version = "0.15.0" | ||||
| dependencies = [ | ||||
|  "paste", | ||||
|  "servicepoint", | ||||
|  "thiserror 2.0.11", | ||||
|  "uniffi", | ||||
|  | @ -466,6 +460,12 @@ 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" | ||||
|  | @ -489,6 +489,15 @@ version = "1.0.1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "textwrap" | ||||
| version = "0.16.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" | ||||
| dependencies = [ | ||||
|  "smawk", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror" | ||||
| version = "1.0.69" | ||||
|  | @ -552,11 +561,13 @@ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" | ||||
| checksum = "4cb08c58c7ed7033150132febe696bef553f891b1ede57424b40d87a89e3c170" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "cargo_metadata", | ||||
|  "uniffi_bindgen", | ||||
|  "uniffi_build", | ||||
|  "uniffi_core", | ||||
|  "uniffi_macros", | ||||
|  | @ -564,9 +575,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_bindgen" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940" | ||||
| checksum = "cade167af943e189a55020eda2c314681e223f1e42aca7c4e52614c2b627698f" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "askama", | ||||
|  | @ -579,17 +590,17 @@ dependencies = [ | |||
|  "once_cell", | ||||
|  "paste", | ||||
|  "serde", | ||||
|  "textwrap", | ||||
|  "toml", | ||||
|  "uniffi_meta", | ||||
|  "uniffi_testing", | ||||
|  "uniffi_udl", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_build" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9" | ||||
| checksum = "4c7cf32576e08104b7dc2a6a5d815f37616e66c6866c2a639fe16e6d2286b75b" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "camino", | ||||
|  | @ -598,9 +609,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_checksum_derive" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" | ||||
| checksum = "802d2051a700e3ec894c79f80d2705b69d85844dafbbe5d1a92776f8f48b563a" | ||||
| dependencies = [ | ||||
|  "quote", | ||||
|  "syn", | ||||
|  | @ -608,25 +619,23 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_core" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b" | ||||
| checksum = "bc7687007d2546c454d8ae609b105daceb88175477dac280707ad6d95bcd6f1f" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "bytes", | ||||
|  "camino", | ||||
|  "log", | ||||
|  "once_cell", | ||||
|  "oneshot-uniffi", | ||||
|  "paste", | ||||
|  "static_assertions", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_macros" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4" | ||||
| checksum = "12c65a5b12ec544ef136693af8759fb9d11aefce740fb76916721e876639033b" | ||||
| dependencies = [ | ||||
|  "bincode", | ||||
|  "camino", | ||||
|  | @ -637,15 +646,14 @@ dependencies = [ | |||
|  "serde", | ||||
|  "syn", | ||||
|  "toml", | ||||
|  "uniffi_build", | ||||
|  "uniffi_meta", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_meta" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2" | ||||
| checksum = "4a74ed96c26882dac1ca9b93ca23c827e284bacbd7ec23c6f0b0372f747d59e4" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "bytes", | ||||
|  | @ -655,9 +663,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_testing" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c" | ||||
| checksum = "6a6f984f0781f892cc864a62c3a5c60361b1ccbd68e538e6c9fbced5d82268ac" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "camino", | ||||
|  | @ -668,11 +676,12 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "uniffi_udl" | ||||
| version = "0.25.3" | ||||
| version = "0.28.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3" | ||||
| checksum = "037820a4cfc4422db1eaa82f291a3863c92c7d1789dc513489c36223f9b4cdfc" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "textwrap", | ||||
|  "uniffi_meta", | ||||
|  "uniffi_testing", | ||||
|  "weedle2", | ||||
|  | @ -686,9 +695,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" | |||
| 
 | ||||
| [[package]] | ||||
| name = "weedle2" | ||||
| version = "4.0.0" | ||||
| version = "5.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" | ||||
| checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" | ||||
| dependencies = [ | ||||
|  "nom", | ||||
| ] | ||||
|  |  | |||
							
								
								
									
										11
									
								
								Cargo.toml
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								Cargo.toml
									
										
									
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| [package] | ||||
| name = "servicepoint_binding_uniffi" | ||||
| version = "0.13.1" | ||||
| version = "0.15.0" | ||||
| publish = false | ||||
| edition = "2021" | ||||
| license = "GPL-3.0-or-later" | ||||
|  | @ -14,15 +14,18 @@ keywords = ["cccb", "cccb-servicepoint", "uniffi"] | |||
| crate-type = ["cdylib"] | ||||
| 
 | ||||
| [build-dependencies] | ||||
| uniffi = { version = "0.25.3", features = ["build"] } | ||||
| uniffi = { version = "0.28.3", features = ["build"] } | ||||
| 
 | ||||
| [dependencies] | ||||
| uniffi = { version = "0.25.3" } | ||||
| uniffi = { version = "0.28.3" } | ||||
| thiserror = "2.0" | ||||
| paste = "1.0.15" | ||||
| 
 | ||||
| [dependencies.servicepoint] | ||||
| version = "0.13.1" | ||||
| version = "0.15.0" | ||||
| features = ["all_compressions"] | ||||
| git = "https://git.berlin.ccc.de/servicepoint/servicepoint.git" | ||||
| branch = "next" | ||||
| 
 | ||||
| [package.metadata.docs.rs] | ||||
| all-features = true | ||||
|  |  | |||
|  | @ -1,77 +0,0 @@ | |||
| use servicepoint::{DataRef, Grid}; | ||||
| use std::sync::{Arc, RwLock}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct Bitmap { | ||||
|     pub(crate) actual: RwLock<servicepoint::Bitmap>, | ||||
| } | ||||
| 
 | ||||
| impl Bitmap { | ||||
|     fn internal_new(actual: servicepoint::Bitmap) -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: RwLock::new(actual), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Bitmap { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Bitmap::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new_max_sized() -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Bitmap::max_sized()) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Bitmap::load( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|             &data, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         Self::internal_new(other.actual.read().unwrap().clone()) | ||||
|     } | ||||
| 
 | ||||
|     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 | ||||
|     } | ||||
| 
 | ||||
|     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<u8> { | ||||
|         self.actual.read().unwrap().data_ref().to_vec() | ||||
|     } | ||||
| } | ||||
|  | @ -1,61 +0,0 @@ | |||
| use std::sync::{Arc, RwLock}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct BitVec { | ||||
|     pub(crate) actual: RwLock<servicepoint::BitVec>, | ||||
| } | ||||
| 
 | ||||
| impl BitVec { | ||||
|     fn internal_new(actual: servicepoint::BitVec) -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: RwLock::new(actual), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BitVec { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(size: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::BitVec::repeat(false, size as usize)) | ||||
|     } | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::BitVec::from_slice(&data)) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         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) | ||||
|     } | ||||
| 
 | ||||
|     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 | ||||
|     } | ||||
| 
 | ||||
|     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<u8> { | ||||
|         self.actual.read().unwrap().clone().into_vec() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/brightness.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/brightness.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| use crate::errors::ServicePointError; | ||||
| use crate::UniffiCustomTypeConverter; | ||||
| use servicepoint::Brightness; | ||||
| 
 | ||||
| uniffi::custom_type!(Brightness, u8); | ||||
| 
 | ||||
| impl UniffiCustomTypeConverter for Brightness { | ||||
|     type Builtin = u8; | ||||
| 
 | ||||
|     fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> | ||||
|     where | ||||
|         Self: Sized, | ||||
|     { | ||||
|         Ok(Brightness::try_from(val) | ||||
|             .map_err(|value| ServicePointError::InvalidBrightness { value })?) | ||||
|     } | ||||
| 
 | ||||
|     fn from_custom(obj: Self) -> Self::Builtin { | ||||
|         obj.into() | ||||
|     } | ||||
| } | ||||
|  | @ -1,86 +0,0 @@ | |||
| use servicepoint::{Brightness, DataRef, Grid}; | ||||
| use std::sync::{Arc, RwLock}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct BrightnessGrid { | ||||
|     pub(crate) actual: RwLock<servicepoint::BrightnessGrid>, | ||||
| } | ||||
| 
 | ||||
| impl BrightnessGrid { | ||||
|     fn internal_new(actual: servicepoint::BrightnessGrid) -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: RwLock::new(actual), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BrightnessGrid { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::BrightnessGrid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::BrightnessGrid::saturating_load( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|             &data, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         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, | ||||
|             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 | ||||
|     } | ||||
| 
 | ||||
|     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<u8> { | ||||
|         self.actual | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .data_ref() | ||||
|             .iter() | ||||
|             .map(u8::from) | ||||
|             .collect() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										169
									
								
								src/char_grid.rs
									
										
									
									
									
								
							
							
						
						
									
										169
									
								
								src/char_grid.rs
									
										
									
									
									
								
							|  | @ -1,169 +0,0 @@ | |||
| use crate::cp437_grid::Cp437Grid; | ||||
| use servicepoint::{Grid, SetValueSeriesError}; | ||||
| use std::convert::Into; | ||||
| use std::sync::{Arc, RwLock}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct CharGrid { | ||||
|     pub(crate) actual: RwLock<servicepoint::CharGrid>, | ||||
| } | ||||
| 
 | ||||
| #[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> { | ||||
|         Self::internal_new(servicepoint::CharGrid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(data: String) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::CharGrid::from(&*data)) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         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::<Vec<_>>()) | ||||
|             .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::<Vec<_>>()) | ||||
|             .map_err(CharGridError::from) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_row(&self, y: u64) -> Result<String, CharGridError> { | ||||
|         self.actual | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .get_row(y as usize) | ||||
|             .map(String::from_iter) | ||||
|             .ok_or(CharGridError::OutOfBounds { | ||||
|                 index: y, | ||||
|                 size: self.height(), | ||||
|             }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_col(&self, x: u64) -> Result<String, CharGridError> { | ||||
|         self.actual | ||||
|             .read() | ||||
|             .unwrap() | ||||
|             .get_col(x as usize) | ||||
|             .map(String::from_iter) | ||||
|             .ok_or(CharGridError::OutOfBounds { | ||||
|                 index: x, | ||||
|                 size: self.width(), | ||||
|             }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn to_cp437(&self) -> Arc<Cp437Grid> { | ||||
|         Cp437Grid::internal_new(servicepoint::Cp437Grid::from( | ||||
|             &*self.actual.read().unwrap(), | ||||
|         )) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CharGrid { | ||||
|     pub(crate) fn internal_new(actual: servicepoint::CharGrid) -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: RwLock::new(actual), | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn str_to_char(value: String) -> Result<char, CharGridError> { | ||||
|         if value.len() != 1 { | ||||
|             return Err(CharGridError::StringNotOneChar { value }); | ||||
|         } | ||||
| 
 | ||||
|         let value = value.chars().nth(0).unwrap(); | ||||
|         Ok(value) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<SetValueSeriesError> for CharGridError { | ||||
|     fn from(e: SetValueSeriesError) -> Self { | ||||
|         match e { | ||||
|             SetValueSeriesError::OutOfBounds { index, size } => { | ||||
|                 CharGridError::OutOfBounds { | ||||
|                     index: index as u64, | ||||
|                     size: size as u64, | ||||
|                 } | ||||
|             } | ||||
|             SetValueSeriesError::InvalidLength { actual, expected } => { | ||||
|                 CharGridError::InvalidSeriesLength { | ||||
|                     actual: actual as u64, | ||||
|                     expected: expected as u64, | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										175
									
								
								src/command.rs
									
										
									
									
									
								
							
							
						
						
									
										175
									
								
								src/command.rs
									
										
									
									
									
								
							|  | @ -1,175 +0,0 @@ | |||
| use crate::bitmap::Bitmap; | ||||
| use crate::bitvec::BitVec; | ||||
| use crate::brightness_grid::BrightnessGrid; | ||||
| use crate::char_grid::CharGrid; | ||||
| use crate::compression_code::CompressionCode; | ||||
| use crate::cp437_grid::Cp437Grid; | ||||
| use crate::errors::ServicePointError; | ||||
| use servicepoint::Origin; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct Command { | ||||
|     pub(crate) actual: servicepoint::Command, | ||||
| } | ||||
| 
 | ||||
| impl Command { | ||||
|     fn internal_new(actual: servicepoint::Command) -> Arc<Command> { | ||||
|         Arc::new(Command { actual }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Command { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clear() -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Command::Clear) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn brightness(brightness: u8) -> Result<Arc<Self>, ServicePointError> { | ||||
|         servicepoint::Brightness::try_from(brightness) | ||||
|             .map_err(move |value| ServicePointError::InvalidBrightness { | ||||
|                 value, | ||||
|             }) | ||||
|             .map(servicepoint::Command::Brightness) | ||||
|             .map(Self::internal_new) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn fade_out() -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Command::FadeOut) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn hard_reset() -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Command::HardReset) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn bitmap_linear_win( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         bitmap: &Arc<Bitmap>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let bitmap = bitmap.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::BitmapLinearWin( | ||||
|             origin, | ||||
|             bitmap, | ||||
|             servicepoint::CompressionCode::try_from(compression as u16) | ||||
|                 .unwrap(), | ||||
|         ); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn char_brightness( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<BrightnessGrid>, | ||||
|     ) -> Arc<Self> { | ||||
|         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<BitVec>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let bitmap = bitmap.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::BitmapLinear( | ||||
|             offset as usize, | ||||
|             bitmap, | ||||
|             servicepoint::CompressionCode::try_from(compression as u16) | ||||
|                 .unwrap(), | ||||
|         ); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn bitmap_linear_and( | ||||
|         offset: u64, | ||||
|         bitmap: &Arc<BitVec>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let bitmap = bitmap.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::BitmapLinearAnd( | ||||
|             offset as usize, | ||||
|             bitmap, | ||||
|             servicepoint::CompressionCode::try_from(compression as u16) | ||||
|                 .unwrap(), | ||||
|         ); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn bitmap_linear_or( | ||||
|         offset: u64, | ||||
|         bitmap: &Arc<BitVec>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let bitmap = bitmap.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::BitmapLinearOr( | ||||
|             offset as usize, | ||||
|             bitmap, | ||||
|             servicepoint::CompressionCode::try_from(compression as u16) | ||||
|                 .unwrap(), | ||||
|         ); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn bitmap_linear_xor( | ||||
|         offset: u64, | ||||
|         bitmap: &Arc<BitVec>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let bitmap = bitmap.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::BitmapLinearXor( | ||||
|             offset as usize, | ||||
|             bitmap, | ||||
|             servicepoint::CompressionCode::try_from(compression as u16) | ||||
|                 .unwrap(), | ||||
|         ); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn cp437_data( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<Cp437Grid>, | ||||
|     ) -> Arc<Self> { | ||||
|         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 utf8_data( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<CharGrid>, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let grid = grid.actual.read().unwrap().clone(); | ||||
|         let actual = servicepoint::Command::Utf8Data(origin, grid); | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         Self::internal_new(other.actual.clone()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn equals(&self, other: &Command) -> bool { | ||||
|         self.actual == other.actual | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								src/commands/bitmap.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/commands/bitmap.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| use crate::{ | ||||
|     commands::wrap_command, compression_code::CompressionCode, | ||||
|     containers::bitmap::Bitmap, macros::wrap_object_attr_wrapped, | ||||
| }; | ||||
| use servicepoint::Origin; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(BitmapCommand); | ||||
| 
 | ||||
| wrap_object_attr_wrapped!(BitmapCommand, bitmap, Bitmap); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BitmapCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         bitmap: &Arc<Bitmap>, | ||||
|         compression: CompressionCode, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let bitmap = bitmap.read().clone(); | ||||
|         let compression = compression.into(); | ||||
|         let actual = servicepoint::BitmapCommand { | ||||
|             origin, | ||||
|             bitmap, | ||||
|             compression, | ||||
|         }; | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								src/commands/bitvec.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/commands/bitvec.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| use crate::{ | ||||
|     commands::wrap_command, compression_code::CompressionCode, | ||||
|     containers::bitvec::BitVec, macros::wrap_object_attr_wrapped, | ||||
| }; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(BitVecCommand); | ||||
| wrap_object_attr_wrapped!(BitVecCommand, bitvec, BitVec); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BitVecCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new( | ||||
|         offset: u64, | ||||
|         bitvec: &Arc<BitVec>, | ||||
|         compression: CompressionCode, | ||||
|         operation: BinaryOperation, | ||||
|     ) -> Arc<Self> { | ||||
|         let offset = offset as usize; | ||||
|         let bitvec = bitvec.read().clone(); | ||||
|         let compression = compression.into(); | ||||
|         let operation = operation.into(); | ||||
|         let actual = servicepoint::BitVecCommand { | ||||
|             offset, | ||||
|             bitvec, | ||||
|             compression, | ||||
|             operation, | ||||
|         }; | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(uniffi::Enum)] | ||||
| pub enum BinaryOperation { | ||||
|     Overwrite, | ||||
|     And, | ||||
|     Or, | ||||
|     Xor, | ||||
| } | ||||
| 
 | ||||
| impl From<BinaryOperation> for servicepoint::BinaryOperation { | ||||
|     fn from(op: BinaryOperation) -> Self { | ||||
|         match op { | ||||
|             BinaryOperation::Overwrite => { | ||||
|                 servicepoint::BinaryOperation::Overwrite | ||||
|             } | ||||
|             BinaryOperation::And => servicepoint::BinaryOperation::And, | ||||
|             BinaryOperation::Or => servicepoint::BinaryOperation::Or, | ||||
|             BinaryOperation::Xor => servicepoint::BinaryOperation::Xor, | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/commands/brightness_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/commands/brightness_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| use crate::{ | ||||
|     commands::wrap_command, containers::brightness_grid::BrightnessGrid, | ||||
|     macros::wrap_object_attr_wrapped, | ||||
| }; | ||||
| use servicepoint::Origin; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(BrightnessGridCommand); | ||||
| wrap_object_attr_wrapped!(BrightnessGridCommand, grid, BrightnessGrid); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BrightnessGridCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<BrightnessGrid>, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let grid = grid.read().clone(); | ||||
|         let actual = servicepoint::BrightnessGridCommand { origin, grid }; | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										19
									
								
								src/commands/cc_only.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/commands/cc_only.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| use std::sync::Arc; | ||||
| 
 | ||||
| macro_rules! command_code_only_command { | ||||
|     ($command_struct:ident) => { | ||||
|         crate::commands::wrap_command!($command_struct); | ||||
| 
 | ||||
|         #[uniffi::export] | ||||
|         impl $command_struct { | ||||
|             #[uniffi::constructor] | ||||
|             pub fn new() -> Arc<Self> { | ||||
|                 Self::internal_new(::servicepoint::$command_struct) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| command_code_only_command!(ClearCommand); | ||||
| command_code_only_command!(HardResetCommand); | ||||
| command_code_only_command!(FadeOutCommand); | ||||
							
								
								
									
										24
									
								
								src/commands/char_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/commands/char_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| use crate::{ | ||||
|     commands::wrap_command, containers::char_grid::CharGrid, | ||||
|     macros::wrap_object_attr_wrapped, | ||||
| }; | ||||
| use servicepoint::Origin; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(CharGridCommand); | ||||
| wrap_object_attr_wrapped!(CharGridCommand, grid, CharGrid); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl CharGridCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<CharGrid>, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let grid = grid.read().clone(); | ||||
|         let actual = servicepoint::CharGridCommand { origin, grid }; | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/commands/cp437.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/commands/cp437.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| use crate::{ | ||||
|     commands::wrap_command, containers::cp437_grid::Cp437Grid, | ||||
|     macros::wrap_object_attr_wrapped, | ||||
| }; | ||||
| use servicepoint::Origin; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(Cp437GridCommand); | ||||
| wrap_object_attr_wrapped!(Cp437GridCommand, grid, Cp437Grid); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Cp437GridCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new( | ||||
|         offset_x: u64, | ||||
|         offset_y: u64, | ||||
|         grid: &Arc<Cp437Grid>, | ||||
|     ) -> Arc<Self> { | ||||
|         let origin = Origin::new(offset_x as usize, offset_y as usize); | ||||
|         let grid = grid.read().clone(); | ||||
|         let actual = servicepoint::Cp437GridCommand { origin, grid }; | ||||
|         Self::internal_new(actual) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/commands/global_brightness.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/commands/global_brightness.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| use crate::commands::wrap_command; | ||||
| use servicepoint::Brightness; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_command!(GlobalBrightnessCommand); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl GlobalBrightnessCommand { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(brightness: Brightness) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::GlobalBrightnessCommand::from( | ||||
|             brightness, | ||||
|         )) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								src/commands/mod.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/commands/mod.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| mod bitmap; | ||||
| mod bitvec; | ||||
| mod brightness_grid; | ||||
| mod cc_only; | ||||
| mod char_grid; | ||||
| mod cp437; | ||||
| mod global_brightness; | ||||
| 
 | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| pub use bitmap::BitmapCommand; | ||||
| pub use bitvec::{BinaryOperation, BitVecCommand}; | ||||
| pub use brightness_grid::BrightnessGridCommand; | ||||
| pub use cc_only::{ClearCommand, FadeOutCommand, HardResetCommand}; | ||||
| pub use char_grid::CharGridCommand; | ||||
| pub use cp437::Cp437GridCommand; | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| pub trait Command: Sync + Send { | ||||
|     fn as_packet( | ||||
|         &self, | ||||
|     ) -> Result<Arc<crate::packet::Packet>, crate::errors::ServicePointError>; | ||||
| } | ||||
| 
 | ||||
| macro_rules! wrap_command { | ||||
|     ($command:ident) => { | ||||
|         crate::macros::wrap_object!($command); | ||||
| 
 | ||||
|         #[uniffi::export] | ||||
|         impl $command { | ||||
|             fn as_packet( | ||||
|                 &self, | ||||
|             ) -> Result< | ||||
|                 Arc<crate::packet::Packet>, | ||||
|                 crate::errors::ServicePointError, | ||||
|             > { | ||||
|                 self.read() | ||||
|                     .clone() | ||||
|                     .try_into() | ||||
|                     .map(crate::packet::Packet::internal_new) | ||||
|                     .map_err(|_| { | ||||
|                         crate::errors::ServicePointError::InvalidPacket | ||||
|                     }) | ||||
|             } | ||||
| 
 | ||||
|             fn as_generic( | ||||
|                 &self, | ||||
|             ) -> ::std::sync::Arc<dyn crate::commands::Command> { | ||||
|                 ::std::sync::Arc::new(self.clone()) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl crate::commands::Command for $command { | ||||
|             fn as_packet( | ||||
|                 &self, | ||||
|             ) -> Result< | ||||
|                 Arc<crate::packet::Packet>, | ||||
|                 crate::errors::ServicePointError, | ||||
|             > { | ||||
|                 $command::as_packet(&self) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| pub(crate) use wrap_command; | ||||
|  | @ -12,3 +12,31 @@ pub enum CompressionCode { | |||
|     /// compress using Zstandard
 | ||||
|     Zstd = 0x7a73, | ||||
| } | ||||
| 
 | ||||
| impl From<servicepoint::CompressionCode> for CompressionCode { | ||||
|     fn from(value: servicepoint::CompressionCode) -> Self { | ||||
|         match value { | ||||
|             servicepoint::CompressionCode::Uncompressed => { | ||||
|                 CompressionCode::Uncompressed | ||||
|             } | ||||
|             servicepoint::CompressionCode::Zlib => CompressionCode::Zlib, | ||||
|             servicepoint::CompressionCode::Bzip2 => CompressionCode::Bzip2, | ||||
|             servicepoint::CompressionCode::Lzma => CompressionCode::Lzma, | ||||
|             servicepoint::CompressionCode::Zstd => CompressionCode::Zstd, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<CompressionCode> for servicepoint::CompressionCode { | ||||
|     fn from(value: CompressionCode) -> Self { | ||||
|         match value { | ||||
|             CompressionCode::Uncompressed => { | ||||
|                 servicepoint::CompressionCode::Uncompressed | ||||
|             } | ||||
|             CompressionCode::Zlib => servicepoint::CompressionCode::Zlib, | ||||
|             CompressionCode::Bzip2 => servicepoint::CompressionCode::Bzip2, | ||||
|             CompressionCode::Lzma => servicepoint::CompressionCode::Lzma, | ||||
|             CompressionCode::Zstd => servicepoint::CompressionCode::Zstd, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,36 +1,39 @@ | |||
| use std::sync::Arc; | ||||
| 
 | ||||
| use crate::command::Command; | ||||
| use crate::errors::ServicePointError; | ||||
| use crate::commands::Command; | ||||
| use crate::{errors::ServicePointError, packet::Packet}; | ||||
| use servicepoint::UdpSocketExt; | ||||
| use std::{net::UdpSocket, sync::Arc}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct Connection { | ||||
|     actual: servicepoint::Connection, | ||||
|     actual: UdpSocket, | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Connection { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(host: String) -> Result<Arc<Self>, ServicePointError> { | ||||
|         servicepoint::Connection::open(host) | ||||
|         UdpSocket::bind_connect(host) | ||||
|             .map(|actual| Arc::new(Connection { actual })) | ||||
|             .map_err(|err| ServicePointError::IoError { | ||||
|                 error: err.to_string(), | ||||
|             }) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new_fake() -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: servicepoint::Connection::Fake, | ||||
|         }) | ||||
|     pub fn send_packet( | ||||
|         &self, | ||||
|         command: Arc<Packet>, | ||||
|     ) -> Result<(), ServicePointError> { | ||||
|         self.actual | ||||
|             .send_command(command.read().clone()) | ||||
|             .ok_or_else(|| ServicePointError::IoError { | ||||
|                 error: "send failed".to_string(), | ||||
|             }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn send(&self, command: Arc<Command>) -> Result<(), ServicePointError> { | ||||
|         self.actual.send(command.actual.clone()).map_err(|err| { | ||||
|             ServicePointError::IoError { | ||||
|                 error: format!("{err:?}"), | ||||
|             } | ||||
|         }) | ||||
|     pub fn send_command( | ||||
|         &self, | ||||
|         command: Arc<dyn Command>, | ||||
|     ) -> Result<(), ServicePointError> { | ||||
|         self.send_packet(command.as_packet()?) | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										38
									
								
								src/containers/bitmap.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/containers/bitmap.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | |||
| use crate::{ | ||||
|     containers::{wrap_get_set_fill_2d, wrap_width_height}, | ||||
|     macros::wrap_object, | ||||
| }; | ||||
| use servicepoint::Grid; | ||||
| use std::{ops::Deref, sync::Arc}; | ||||
| 
 | ||||
| wrap_object!(Bitmap); | ||||
| wrap_width_height!(Bitmap); | ||||
| wrap_get_set_fill_2d!(Bitmap, bool); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Bitmap { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new( | ||||
|             servicepoint::Bitmap::new(width as usize, height as usize).unwrap(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new_max_sized() -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Bitmap::max_sized()) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         // TODO: throw exception
 | ||||
|         Self::internal_new( | ||||
|             servicepoint::Bitmap::load(width as usize, height as usize, &data) | ||||
|                 .unwrap(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     pub fn copy_raw(&self) -> Vec<u8> { | ||||
|         self.read().deref().into() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										39
									
								
								src/containers/bitvec.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/containers/bitvec.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| use crate::macros::wrap_object; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_object!(DisplayBitVec, BitVec); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BitVec { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(size: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::DisplayBitVec::repeat( | ||||
|             false, | ||||
|             size as usize, | ||||
|         )) | ||||
|     } | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::DisplayBitVec::from_slice(&data)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn set(&self, index: u64, value: bool) { | ||||
|         self.write().set(index as usize, value) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get(&self, index: u64) -> bool { | ||||
|         self.read().get(index as usize).is_some_and(move |bit| *bit) | ||||
|     } | ||||
| 
 | ||||
|     pub fn fill(&self, value: bool) { | ||||
|         self.write().fill(value) | ||||
|     } | ||||
| 
 | ||||
|     pub fn len(&self) -> u64 { | ||||
|         self.read().len() as u64 | ||||
|     } | ||||
| 
 | ||||
|     pub fn copy_raw(&self) -> Vec<u8> { | ||||
|         self.read().clone().into_vec() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										37
									
								
								src/containers/brightness_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/containers/brightness_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| use crate::{ | ||||
|     containers::{wrap_get_set_fill_2d, wrap_width_height}, | ||||
|     macros::wrap_object, | ||||
| }; | ||||
| use servicepoint::{Brightness, Grid}; | ||||
| use std::{ops::Deref, sync::Arc}; | ||||
| 
 | ||||
| wrap_object!(BrightnessGrid); | ||||
| wrap_width_height!(BrightnessGrid); | ||||
| wrap_get_set_fill_2d!(BrightnessGrid, Brightness); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl BrightnessGrid { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::BrightnessGrid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new( | ||||
|             servicepoint::BrightnessGrid::saturating_load( | ||||
|                 width as usize, | ||||
|                 height as usize, | ||||
|                 &data, | ||||
|             ) | ||||
|             .unwrap(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     pub fn copy_raw(&self) -> Vec<u8> { | ||||
|         self.read().deref().into() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										123
									
								
								src/containers/char_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/containers/char_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,123 @@ | |||
| use crate::{ | ||||
|     containers::{cp437_grid::Cp437Grid, wrap_width_height}, | ||||
|     errors::ServicePointError, | ||||
|     macros::wrap_object, | ||||
| }; | ||||
| use servicepoint::{Grid, SetValueSeriesError}; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| wrap_object!(CharGrid); | ||||
| wrap_width_height!(CharGrid); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl CharGrid { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::CharGrid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(data: String) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::CharGrid::from(&*data)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn set( | ||||
|         &self, | ||||
|         x: u64, | ||||
|         y: u64, | ||||
|         value: String, | ||||
|     ) -> Result<(), ServicePointError> { | ||||
|         let value = Self::str_to_char(value)?; | ||||
|         if self.write().set_optional(x as isize, y as isize, value) { | ||||
|             Ok(()) | ||||
|         } else { | ||||
|             Err(ServicePointError::OutOfBounds) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get(&self, x: u64, y: u64) -> Result<String, ServicePointError> { | ||||
|         self.read() | ||||
|             .get_optional(x as isize, y as isize) | ||||
|             .ok_or(ServicePointError::OutOfBounds) | ||||
|             .map(String::from) | ||||
|     } | ||||
| 
 | ||||
|     pub fn fill(&self, value: String) -> Result<(), ServicePointError> { | ||||
|         let value = Self::str_to_char(value)?; | ||||
|         self.write().fill(value); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn as_string(&self) -> String { | ||||
|         let grid = self.read(); | ||||
|         String::from(&*grid) | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_row( | ||||
|         &self, | ||||
|         y: u64, | ||||
|         row: String, | ||||
|     ) -> Result<(), ServicePointError> { | ||||
|         self.write() | ||||
|             .set_row(y as usize, &row.chars().collect::<Vec<_>>()) | ||||
|             .map_err(ServicePointError::from) | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_col( | ||||
|         &self, | ||||
|         x: u64, | ||||
|         col: String, | ||||
|     ) -> Result<(), ServicePointError> { | ||||
|         self.write() | ||||
|             .set_row(x as usize, &col.chars().collect::<Vec<_>>()) | ||||
|             .map_err(ServicePointError::from) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_row(&self, y: u64) -> Result<String, ServicePointError> { | ||||
|         self.read() | ||||
|             .get_row(y as usize) | ||||
|             .map(String::from_iter) | ||||
|             .ok_or(ServicePointError::OutOfBounds) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_col(&self, x: u64) -> Result<String, ServicePointError> { | ||||
|         self.read() | ||||
|             .get_col(x as usize) | ||||
|             .map(String::from_iter) | ||||
|             .ok_or(ServicePointError::OutOfBounds) | ||||
|     } | ||||
| 
 | ||||
|     pub fn to_cp437(&self) -> Arc<Cp437Grid> { | ||||
|         Cp437Grid::internal_new(servicepoint::Cp437Grid::from(&*self.read())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CharGrid { | ||||
|     fn str_to_char(value: String) -> Result<char, ServicePointError> { | ||||
|         if value.len() != 1 { | ||||
|             return Err(ServicePointError::StringNotOneChar { value }); | ||||
|         } | ||||
| 
 | ||||
|         let value = value.chars().nth(0).unwrap(); | ||||
|         Ok(value) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<SetValueSeriesError> for ServicePointError { | ||||
|     fn from(e: SetValueSeriesError) -> Self { | ||||
|         match e { | ||||
|             SetValueSeriesError::OutOfBounds { .. } => { | ||||
|                 ServicePointError::OutOfBounds | ||||
|             } | ||||
|             SetValueSeriesError::InvalidLength { actual, expected } => { | ||||
|                 ServicePointError::InvalidSeriesLength { | ||||
|                     actual: actual as u64, | ||||
|                     expected: expected as u64, | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/containers/cp437_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/containers/cp437_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| use crate::{ | ||||
|     containers::char_grid::CharGrid, | ||||
|     containers::{wrap_get_set_fill_2d, wrap_width_height}, | ||||
|     macros::wrap_object, | ||||
| }; | ||||
| use servicepoint::Grid; | ||||
| use std::{ops::Deref, sync::Arc}; | ||||
| 
 | ||||
| wrap_object!(Cp437Grid); | ||||
| wrap_width_height!(Cp437Grid); | ||||
| wrap_get_set_fill_2d!(Cp437Grid, u8); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Cp437Grid { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Cp437Grid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new( | ||||
|             servicepoint::Cp437Grid::load( | ||||
|                 width as usize, | ||||
|                 height as usize, | ||||
|                 &data, | ||||
|             ) | ||||
|             .unwrap(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     pub fn copy_raw(&self) -> Vec<u8> { | ||||
|         self.read().deref().into() | ||||
|     } | ||||
| 
 | ||||
|     pub fn to_utf8(&self) -> Arc<CharGrid> { | ||||
|         CharGrid::internal_new(servicepoint::CharGrid::from(&*self.read())) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/containers/mod.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/containers/mod.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| pub mod bitmap; | ||||
| pub mod bitvec; | ||||
| pub mod brightness_grid; | ||||
| pub mod char_grid; | ||||
| pub mod cp437_grid; | ||||
| 
 | ||||
| macro_rules! wrap_width_height { | ||||
|     ($t:ident) => { | ||||
|         #[uniffi::export] | ||||
|         impl $t { | ||||
|             pub fn width(&self) -> u64 { | ||||
|                 self.read().width() as u64 | ||||
|             } | ||||
| 
 | ||||
|             pub fn height(&self) -> u64 { | ||||
|                 self.read().height() as u64 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| pub(crate) use wrap_width_height; | ||||
| 
 | ||||
| macro_rules! wrap_get_set_fill_2d { | ||||
|     ($t:ident, $contained:ident) => { | ||||
|         #[uniffi::export] | ||||
|         impl $t { | ||||
|             pub fn set(&self, x: u64, y: u64, value: $contained) { | ||||
|                 self.actual | ||||
|                     .write() | ||||
|                     .unwrap() | ||||
|                     .set(x as usize, y as usize, value) | ||||
|             } | ||||
| 
 | ||||
|             pub fn get(&self, x: u64, y: u64) -> $contained { | ||||
|                 self.read().get(x as usize, y as usize) | ||||
|             } | ||||
| 
 | ||||
|             pub fn fill(&self, value: $contained) { | ||||
|                 self.actual.write().unwrap().fill(value) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| pub(crate) use wrap_get_set_fill_2d; | ||||
|  | @ -1,79 +0,0 @@ | |||
| use crate::char_grid::CharGrid; | ||||
| use servicepoint::{DataRef, Grid}; | ||||
| use std::sync::{Arc, RwLock}; | ||||
| 
 | ||||
| #[derive(uniffi::Object)] | ||||
| pub struct Cp437Grid { | ||||
|     pub(crate) actual: RwLock<servicepoint::Cp437Grid>, | ||||
| } | ||||
| 
 | ||||
| impl Cp437Grid { | ||||
|     pub(crate) fn internal_new(actual: servicepoint::Cp437Grid) -> Arc<Self> { | ||||
|         Arc::new(Self { | ||||
|             actual: RwLock::new(actual), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Cp437Grid { | ||||
|     #[uniffi::constructor] | ||||
|     pub fn new(width: u64, height: u64) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Cp437Grid::new( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> { | ||||
|         Self::internal_new(servicepoint::Cp437Grid::load( | ||||
|             width as usize, | ||||
|             height as usize, | ||||
|             &data, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     #[uniffi::constructor] | ||||
|     pub fn clone(other: &Arc<Self>) -> Arc<Self> { | ||||
|         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) | ||||
|     } | ||||
| 
 | ||||
|     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<u8> { | ||||
|         self.actual.read().unwrap().data_ref().to_vec() | ||||
|     } | ||||
| 
 | ||||
|     pub fn to_utf8(&self) -> Arc<CharGrid> { | ||||
|         CharGrid::internal_new(servicepoint::CharGrid::from( | ||||
|             &*self.actual.read().unwrap(), | ||||
|         )) | ||||
|     } | ||||
| } | ||||
|  | @ -4,4 +4,12 @@ pub enum ServicePointError { | |||
|     IoError { error: String }, | ||||
|     #[error("The specified brightness value {value} is out of range")] | ||||
|     InvalidBrightness { value: u8 }, | ||||
|     #[error("The provided packet is invalid or a conversion to packet failed")] | ||||
|     InvalidPacket, | ||||
|     #[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 was out of bounds")] | ||||
|     OutOfBounds, | ||||
| } | ||||
|  |  | |||
							
								
								
									
										19
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								src/lib.rs
									
										
									
									
									
								
							|  | @ -1,12 +1,11 @@ | |||
| uniffi::setup_scaffolding!(); | ||||
| 
 | ||||
| mod bitmap; | ||||
| mod bitvec; | ||||
| mod brightness_grid; | ||||
| mod char_grid; | ||||
| mod command; | ||||
| mod compression_code; | ||||
| mod connection; | ||||
| mod constants; | ||||
| mod cp437_grid; | ||||
| mod errors; | ||||
| pub mod brightness; | ||||
| pub mod commands; | ||||
| pub mod compression_code; | ||||
| pub mod connection; | ||||
| pub mod constants; | ||||
| pub mod containers; | ||||
| pub mod errors; | ||||
| pub mod macros; | ||||
| mod packet; | ||||
|  |  | |||
							
								
								
									
										128
									
								
								src/macros.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/macros.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,128 @@ | |||
| macro_rules! wrap_object { | ||||
|     ($orig_t:ident, $new_t:ident) => { | ||||
|         #[derive(uniffi::Object)] | ||||
|         #[uniffi::export(Debug, Eq, Hash)] | ||||
|         pub struct $new_t { | ||||
|             actual: ::std::sync::RwLock<::servicepoint::$orig_t>, | ||||
|         } | ||||
| 
 | ||||
|         #[allow(unused)] | ||||
|         impl $new_t { | ||||
|             pub(crate) fn internal_new( | ||||
|                 actual: ::servicepoint::$orig_t, | ||||
|             ) -> ::std::sync::Arc<Self> { | ||||
|                 ::std::sync::Arc::new(Self::internal_new_noarc(actual)) | ||||
|             } | ||||
| 
 | ||||
|             pub(crate) fn internal_new_noarc( | ||||
|                 actual: ::servicepoint::$orig_t, | ||||
|             ) -> Self { | ||||
|                 Self { | ||||
|                     actual: ::std::sync::RwLock::new(actual), | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             pub(crate) fn read( | ||||
|                 &self, | ||||
|             ) -> ::std::sync::RwLockReadGuard<::servicepoint::$orig_t> { | ||||
|                 self.actual.read().unwrap() | ||||
|             } | ||||
| 
 | ||||
|             pub(crate) fn write( | ||||
|                 &self, | ||||
|             ) -> ::std::sync::RwLockWriteGuard<::servicepoint::$orig_t> { | ||||
|                 self.actual.write().unwrap() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         #[uniffi::export] | ||||
|         impl $new_t { | ||||
|             #[uniffi::constructor] | ||||
|             pub fn clone( | ||||
|                 other: &::std::sync::Arc<Self>, | ||||
|             ) -> ::std::sync::Arc<Self> { | ||||
|                 Self::internal_new(other.read().clone()) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Clone for $new_t { | ||||
|             fn clone(&self) -> Self { | ||||
|                 Self::internal_new_noarc(self.read().clone()) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl ::std::fmt::Debug for $new_t { | ||||
|             fn fmt( | ||||
|                 &self, | ||||
|                 f: &mut ::std::fmt::Formatter, | ||||
|             ) -> Result<(), std::fmt::Error> { | ||||
|                 f.write_fmt(format_args!("{:?}", self.read())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl PartialEq for $new_t { | ||||
|             fn eq(&self, other: &$new_t) -> bool { | ||||
|                 *self.read() == *other.read() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Eq for $new_t {} | ||||
| 
 | ||||
|         impl ::std::hash::Hash for $new_t { | ||||
|             fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) { | ||||
|                 ::std::hash::Hash::hash(&*self.read(), state) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     ($t:ident) => { | ||||
|         crate::macros::wrap_object!($t, $t); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! wrap_object_attr_wrapped_get { | ||||
|     ($object:ident, $attr_name:ident, $attr_type:ident, $fun_name:ident) => { | ||||
|         #[uniffi::export] | ||||
|         impl $object { | ||||
|             pub fn $fun_name(&self) -> ::std::sync::Arc<$attr_type> { | ||||
|                 $attr_type::internal_new(self.read().$attr_name.clone()) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     ($object:ident, $attr_name:ident, $attr_type:ident) => { | ||||
|         paste::paste!{ | ||||
|             crate::macros::wrap_object_attr_wrapped_get!($object, $attr_name, $attr_type, [<get_ $attr_name>]); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! wrap_object_attr_wrapped_set { | ||||
|     ($object:ident, $attr_name:ident, $attr_type:ident, $fun_name:ident) => { | ||||
|         #[uniffi::export] | ||||
|         impl $object { | ||||
|             pub fn $fun_name(&self, $attr_name: ::std::sync::Arc<$attr_type>) { | ||||
|                 self.write().$attr_name = $attr_name.read().clone(); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     ($object:ident, $attr_name:ident, $attr_type:ident) => { | ||||
|         paste::paste!{ | ||||
|             crate::macros::wrap_object_attr_wrapped_set!($object, $attr_name, $attr_type, [<set_ $attr_name>]); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! wrap_object_attr_wrapped { | ||||
|     ($object:ident, $attr_name:ident, $attr_type:ident) => { | ||||
|         crate::macros::wrap_object_attr_wrapped_get!( | ||||
|             $object, $attr_name, $attr_type | ||||
|         ); | ||||
|         crate::macros::wrap_object_attr_wrapped_set!( | ||||
|             $object, $attr_name, $attr_type | ||||
|         ); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| pub(crate) use { | ||||
|     wrap_object, wrap_object_attr_wrapped, wrap_object_attr_wrapped_get, | ||||
|     wrap_object_attr_wrapped_set, | ||||
| }; | ||||
							
								
								
									
										13
									
								
								src/packet.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/packet.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| use crate::macros::{wrap_object, wrap_object_attr_wrapped}; | ||||
| 
 | ||||
| wrap_object!(Packet); | ||||
| wrap_object!(Header); | ||||
| 
 | ||||
| wrap_object_attr_wrapped!(Packet, header, Header); | ||||
| 
 | ||||
| #[uniffi::export] | ||||
| impl Packet { | ||||
|     pub fn as_bytes(&self) -> Vec<u8> { | ||||
|         Vec::from(&*self.read()) | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue