From b00c662b951d052a024ef003a9dd0983eb87cd00 Mon Sep 17 00:00:00 2001 From: Elijah R Date: Sun, 4 Aug 2024 15:59:39 -0400 Subject: [PATCH] make rustfmt.toml consistent with editorconfig because of course rustfmt refuses to use the editorconfig --- cvm-rs/rustfmt.toml | 3 + cvm-rs/src/guac.rs | 238 +++++++++++++++++----------------- cvm-rs/src/guac_js.rs | 52 ++++---- cvm-rs/src/jpeg_compressor.rs | 118 ++++++++--------- cvm-rs/src/jpeg_js.rs | 100 +++++++------- cvm-rs/src/lib.rs | 10 +- 6 files changed, 262 insertions(+), 259 deletions(-) create mode 100644 cvm-rs/rustfmt.toml diff --git a/cvm-rs/rustfmt.toml b/cvm-rs/rustfmt.toml new file mode 100644 index 0000000..fd823cd --- /dev/null +++ b/cvm-rs/rustfmt.toml @@ -0,0 +1,3 @@ +tab_spaces = 4 +newline_style = "Unix" +hard_tabs = true \ No newline at end of file diff --git a/cvm-rs/src/guac.rs b/cvm-rs/src/guac.rs index c87bf5d..a83517b 100644 --- a/cvm-rs/src/guac.rs +++ b/cvm-rs/src/guac.rs @@ -8,30 +8,30 @@ pub type Elements = Vec; /// Errors during decoding #[derive(Debug, Clone)] pub enum DecodeError { - /// Invalid guacamole instruction format - InvalidFormat, + /// Invalid guacamole instruction format + InvalidFormat, - /// Instruction is too long for the current decode policy. - InstructionTooLong, + /// Instruction is too long for the current decode policy. + InstructionTooLong, - /// Element is too long for the current decode policy. - ElementTooLong, + /// Element is too long for the current decode policy. + ElementTooLong, - /// Invalid element size. - ElementSizeInvalid, + /// Invalid element size. + ElementSizeInvalid, } pub type DecodeResult = std::result::Result; impl fmt::Display for DecodeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::InvalidFormat => write!(f, "Invalid Guacamole instruction while decoding"), - Self::InstructionTooLong => write!(f, "Instruction too long for current decode policy"), - Self::ElementTooLong => write!(f, "Element too long for current decode policy"), - Self::ElementSizeInvalid => write!(f, "Element size is invalid"), - } - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidFormat => write!(f, "Invalid Guacamole instruction while decoding"), + Self::InstructionTooLong => write!(f, "Instruction too long for current decode policy"), + Self::ElementTooLong => write!(f, "Element too long for current decode policy"), + Self::ElementSizeInvalid => write!(f, "Element size is invalid"), + } + } } // this decode policy abstraction would in theory be useful, @@ -40,13 +40,13 @@ impl fmt::Display for DecodeError { pub struct StaticDecodePolicy(); impl StaticDecodePolicy { - fn max_instruction_size(&self) -> usize { - INST_SIZE - } + fn max_instruction_size(&self) -> usize { + INST_SIZE + } - fn max_element_size(&self) -> usize { - ELEM_SIZE - } + fn max_element_size(&self) -> usize { + ELEM_SIZE + } } /// The default decode policy. @@ -54,139 +54,139 @@ pub type DefaultDecodePolicy = StaticDecodePolicy<12288, 4096>; /// Encodes elements into a Guacamole instruction pub fn encode_instruction(elements: &Elements) -> String { - let mut str = String::new(); + let mut str = String::new(); - for elem in elements.iter() { - str.push_str(&format!("{}.{},", elem.len(), elem)); - } + for elem in elements.iter() { + str.push_str(&format!("{}.{},", elem.len(), elem)); + } - // hacky, but whatever - str.pop(); - str.push(';'); + // hacky, but whatever + str.pop(); + str.push(';'); - str + str } /// Decodes a Guacamole instruction to individual elements pub fn decode_instruction(element_string: &String) -> DecodeResult { - let policy = DefaultDecodePolicy {}; + let policy = DefaultDecodePolicy {}; - let mut vec: Elements = Vec::new(); - let mut current_position: usize = 0; + let mut vec: Elements = Vec::new(); + let mut current_position: usize = 0; - // Instruction is too long. Don't even bother - if policy.max_instruction_size() < element_string.len() { - return Err(DecodeError::InstructionTooLong); - } + // Instruction is too long. Don't even bother + if policy.max_instruction_size() < element_string.len() { + return Err(DecodeError::InstructionTooLong); + } - let chars = element_string.chars().collect::>(); + let chars = element_string.chars().collect::>(); - loop { - let mut element_size: usize = 0; + loop { + let mut element_size: usize = 0; - // Scan the integer value in by hand. This is mostly because - // I'm stupid, and the Rust integer parsing routines (seemingly) - // require a substring (or a slice, but, if you can generate a slice, - // you can also just scan the value in by hand.) - // - // We bound this anyways and do quite the checks, so even though it's not great, - // it should be generally fine (TM). - loop { - let c = chars[current_position]; + // Scan the integer value in by hand. This is mostly because + // I'm stupid, and the Rust integer parsing routines (seemingly) + // require a substring (or a slice, but, if you can generate a slice, + // you can also just scan the value in by hand.) + // + // We bound this anyways and do quite the checks, so even though it's not great, + // it should be generally fine (TM). + loop { + let c = chars[current_position]; - if c >= '0' && c <= '9' { - element_size = element_size * 10 + (c as usize) - ('0' as usize); - } else { - if c == '.' { - break; - } + if c >= '0' && c <= '9' { + element_size = element_size * 10 + (c as usize) - ('0' as usize); + } else { + if c == '.' { + break; + } - return Err(DecodeError::InvalidFormat); - } - current_position += 1; - } + return Err(DecodeError::InvalidFormat); + } + current_position += 1; + } - // Eat the '.' seperating the size and the element data; - // our integer scanning ensures we only get here in the case that this is actually the '.' - // character. - current_position += 1; + // Eat the '.' seperating the size and the element data; + // our integer scanning ensures we only get here in the case that this is actually the '.' + // character. + current_position += 1; - // Make sure the element size doesn't overflow the decode policy - // or the size of the whole instruction. + // Make sure the element size doesn't overflow the decode policy + // or the size of the whole instruction. - if element_size >= policy.max_element_size() { - return Err(DecodeError::ElementTooLong); - } + if element_size >= policy.max_element_size() { + return Err(DecodeError::ElementTooLong); + } - if element_size >= element_string.len() { - return Err(DecodeError::ElementSizeInvalid); - } + if element_size >= element_string.len() { + return Err(DecodeError::ElementSizeInvalid); + } - // cutoff elements or something - if current_position + element_size > chars.len() - 1 { - //println!("? {current_position} a {}", chars.len()); - return Err(DecodeError::InvalidFormat); - } + // cutoff elements or something + if current_position + element_size > chars.len() - 1 { + //println!("? {current_position} a {}", chars.len()); + return Err(DecodeError::InvalidFormat); + } - let element = chars - .iter() - .skip(current_position) - .take(element_size) - .collect::(); + let element = chars + .iter() + .skip(current_position) + .take(element_size) + .collect::(); - current_position += element_size; + current_position += element_size; - vec.push(element); + vec.push(element); - // make sure seperator is proper - match chars[current_position] { - ',' => {} - ';' => break, - _ => return Err(DecodeError::InvalidFormat), - } + // make sure seperator is proper + match chars[current_position] { + ',' => {} + ';' => break, + _ => return Err(DecodeError::InvalidFormat), + } - // eat the ',' - current_position += 1; - } + // eat the ',' + current_position += 1; + } - Ok(vec) + Ok(vec) } #[cfg(test)] mod tests { - use super::*; + use super::*; - #[test] - fn decode_basic() { - let test = String::from("7.connect,3.vm1;"); - let res = decode_instruction(&test); + #[test] + fn decode_basic() { + let test = String::from("7.connect,3.vm1;"); + let res = decode_instruction(&test); - assert!(res.is_ok()); - assert_eq!(res.unwrap(), vec!["connect", "vm1"]); - } + assert!(res.is_ok()); + assert_eq!(res.unwrap(), vec!["connect", "vm1"]); + } - #[test] - fn decode_errors() { - let test = String::from("700.connect,3.vm1;"); - let res = decode_instruction(&test); + #[test] + fn decode_errors() { + let test = String::from("700.connect,3.vm1;"); + let res = decode_instruction(&test); - eprintln!("Error for: {}", res.clone().unwrap_err()); + eprintln!("Error for: {}", res.clone().unwrap_err()); - assert!(res.is_err()) - } + assert!(res.is_err()) + } - // generally just test that the codec even works - // (we can decode a instruction we created) - #[test] - fn general_codec_works() { - let vec = vec![String::from("connect"), String::from("vm1")]; - let test = encode_instruction(&vec); + // generally just test that the codec even works + // (we can decode a instruction we created) + #[test] + fn general_codec_works() { + let vec = vec![String::from("connect"), String::from("vm1")]; + let test = encode_instruction(&vec); - assert_eq!(test, "7.connect,3.vm1;"); + assert_eq!(test, "7.connect,3.vm1;"); - let res = decode_instruction(&test); + let res = decode_instruction(&test); - assert!(res.is_ok()); - assert_eq!(res.unwrap(), vec); - } + assert!(res.is_ok()); + assert_eq!(res.unwrap(), vec); + } } diff --git a/cvm-rs/src/guac_js.rs b/cvm-rs/src/guac_js.rs index 4a9aaee..dde9690 100644 --- a/cvm-rs/src/guac_js.rs +++ b/cvm-rs/src/guac_js.rs @@ -2,46 +2,46 @@ use crate::guac; use neon::prelude::*; fn guac_decode_impl<'a>(cx: &mut FunctionContext<'a>) -> JsResult<'a, JsArray> { - let input = cx.argument::(0)?.value(cx); + let input = cx.argument::(0)?.value(cx); - match guac::decode_instruction(&input) { - Ok(data) => { - let array = JsArray::new(cx, data.len()); + match guac::decode_instruction(&input) { + Ok(data) => { + let array = JsArray::new(cx, data.len()); - let conv = data - .iter() - .map(|v| cx.string(v)) - .collect::>>(); + let conv = data + .iter() + .map(|v| cx.string(v)) + .collect::>>(); - for (i, str) in conv.iter().enumerate() { - array.set(cx, i as u32, *str)?; - } + for (i, str) in conv.iter().enumerate() { + array.set(cx, i as u32, *str)?; + } - return Ok(array); - } + return Ok(array); + } - Err(e) => { - return cx.throw_error(format!("{}", e)); - } - } + Err(e) => { + return cx.throw_error(format!("{}", e)); + } + } } fn guac_encode_impl<'a>(cx: &mut FunctionContext<'a>) -> JsResult<'a, JsString> { - let mut elements: Vec = Vec::with_capacity(cx.len()); + let mut elements: Vec = Vec::with_capacity(cx.len()); - // Capture varadic arguments - for i in 0..cx.len() { - let input = cx.argument::(i)?.value(cx); - elements.push(input); - } + // Capture varadic arguments + for i in 0..cx.len() { + let input = cx.argument::(i)?.value(cx); + elements.push(input); + } - Ok(cx.string(guac::encode_instruction(&elements))) + Ok(cx.string(guac::encode_instruction(&elements))) } pub fn guac_decode(mut cx: FunctionContext) -> JsResult { - guac_decode_impl(&mut cx) + guac_decode_impl(&mut cx) } pub fn guac_encode(mut cx: FunctionContext) -> JsResult { - guac_encode_impl(&mut cx) + guac_encode_impl(&mut cx) } diff --git a/cvm-rs/src/jpeg_compressor.rs b/cvm-rs/src/jpeg_compressor.rs index f716192..2030efe 100644 --- a/cvm-rs/src/jpeg_compressor.rs +++ b/cvm-rs/src/jpeg_compressor.rs @@ -1,82 +1,82 @@ use turbojpeg_sys::*; pub struct Image<'a> { - pub buffer: &'a [u8], - pub width: u32, - pub height: u32, - pub stride: u32, - pub format: TJPF, + pub buffer: &'a [u8], + pub width: u32, + pub height: u32, + pub stride: u32, + pub format: TJPF, } pub struct JpegCompressor { - handle: tjhandle, - subsamp: TJSAMP, - quality: u32, + handle: tjhandle, + subsamp: TJSAMP, + quality: u32, } unsafe impl Send for JpegCompressor {} impl JpegCompressor { - pub fn new() -> Self { - unsafe { - let init = Self { - handle: tjInitCompress(), - subsamp: TJSAMP_TJSAMP_422, - quality: 95, - }; - return init; - } - } + pub fn new() -> Self { + unsafe { + let init = Self { + handle: tjInitCompress(), + subsamp: TJSAMP_TJSAMP_422, + quality: 95, + }; + return init; + } + } - pub fn set_quality(&mut self, quality: u32) { - self.quality = quality; - } + pub fn set_quality(&mut self, quality: u32) { + self.quality = quality; + } - pub fn set_subsamp(&mut self, samp: TJSAMP) { - self.subsamp = samp; - } + pub fn set_subsamp(&mut self, samp: TJSAMP) { + self.subsamp = samp; + } - pub fn compress_buffer<'a>(&self, image: &Image<'a>) -> Vec { - unsafe { - let size: usize = - tjBufSize(image.width as i32, image.height as i32, self.subsamp) as usize; - let mut vec = Vec::with_capacity(size); + pub fn compress_buffer<'a>(&self, image: &Image<'a>) -> Vec { + unsafe { + let size: usize = + tjBufSize(image.width as i32, image.height as i32, self.subsamp) as usize; + let mut vec = Vec::with_capacity(size); - vec.resize(size, 0); + vec.resize(size, 0); - let mut ptr: *mut u8 = vec.as_mut_ptr(); - let mut size: libc::c_ulong = 0; + let mut ptr: *mut u8 = vec.as_mut_ptr(); + let mut size: libc::c_ulong = 0; - let res = tjCompress2( - self.handle, - image.buffer.as_ptr(), - image.width as i32, - image.stride as i32, - image.height as i32, - image.format, - std::ptr::addr_of_mut!(ptr), - std::ptr::addr_of_mut!(size), - self.subsamp, - self.quality as i32, - (TJFLAG_NOREALLOC) as i32, - ); + let res = tjCompress2( + self.handle, + image.buffer.as_ptr(), + image.width as i32, + image.stride as i32, + image.height as i32, + image.format, + std::ptr::addr_of_mut!(ptr), + std::ptr::addr_of_mut!(size), + self.subsamp, + self.quality as i32, + (TJFLAG_NOREALLOC) as i32, + ); - // TODO: Result sex so we can actually notify failure - if res == -1 { - return Vec::new(); - } + // TODO: Result sex so we can actually notify failure + if res == -1 { + return Vec::new(); + } - // Truncate down to the size we're given back - vec.truncate(size as usize); - return vec; - } - } + // Truncate down to the size we're given back + vec.truncate(size as usize); + return vec; + } + } } impl Drop for JpegCompressor { - fn drop(&mut self) { - unsafe { - tjDestroy(self.handle); - } - } + fn drop(&mut self) { + unsafe { + tjDestroy(self.handle); + } + } } diff --git a/cvm-rs/src/jpeg_js.rs b/cvm-rs/src/jpeg_js.rs index 4547036..e13b557 100644 --- a/cvm-rs/src/jpeg_js.rs +++ b/cvm-rs/src/jpeg_js.rs @@ -13,75 +13,75 @@ use crate::jpeg_compressor::*; /// Gives a static Tokio runtime. We should replace this with /// rayon or something, but for now tokio works. fn runtime<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<&'static Runtime> { - static RUNTIME: OnceCell = OnceCell::new(); + static RUNTIME: OnceCell = OnceCell::new(); - RUNTIME - .get_or_try_init(Runtime::new) - .or_else(|err| cx.throw_error(&err.to_string())) + RUNTIME + .get_or_try_init(Runtime::new) + .or_else(|err| cx.throw_error(&err.to_string())) } thread_local! { - static COMPRESSOR: RefCell = RefCell::new(JpegCompressor::new()); + static COMPRESSOR: RefCell = RefCell::new(JpegCompressor::new()); } fn jpeg_encode_impl<'a>(cx: &mut FunctionContext<'a>) -> JsResult<'a, JsPromise> { - let input = cx.argument::(0)?; + let input = cx.argument::(0)?; - // Get our input arguments here - let width: u64 = input.get::(cx, "width")?.value(cx) as u64; - let height: u64 = input.get::(cx, "height")?.value(cx) as u64; - let stride: u64 = input.get::(cx, "stride")?.value(cx) as u64; - let buffer: Handle = input.get(cx, "buffer")?; + // Get our input arguments here + let width: u64 = input.get::(cx, "width")?.value(cx) as u64; + let height: u64 = input.get::(cx, "height")?.value(cx) as u64; + let stride: u64 = input.get::(cx, "stride")?.value(cx) as u64; + let buffer: Handle = input.get(cx, "buffer")?; - let (deferred, promise) = cx.promise(); - let channel = cx.channel(); - let runtime = runtime(cx)?; + let (deferred, promise) = cx.promise(); + let channel = cx.channel(); + let runtime = runtime(cx)?; - let buf = buffer.as_slice(cx); + let buf = buffer.as_slice(cx); - let copy: Arc>> = Arc::new(Mutex::new(Vec::with_capacity(buf.len()))); + let copy: Arc>> = Arc::new(Mutex::new(Vec::with_capacity(buf.len()))); - // Copy from the node buffer to our temporary buffer - { - let mut locked = copy.lock().unwrap(); - let cap = locked.capacity(); - locked.resize(cap, 0); - locked.copy_from_slice(buf); - } + // Copy from the node buffer to our temporary buffer + { + let mut locked = copy.lock().unwrap(); + let cap = locked.capacity(); + locked.resize(cap, 0); + locked.copy_from_slice(buf); + } - // Spawn off a tokio blocking pool thread that will do the work for us - runtime.spawn_blocking(move || { - let clone = Arc::clone(©); - let locked = clone.lock().unwrap(); + // Spawn off a tokio blocking pool thread that will do the work for us + runtime.spawn_blocking(move || { + let clone = Arc::clone(©); + let locked = clone.lock().unwrap(); - let image: Image = Image { - buffer: locked.as_slice(), - width: width as u32, - height: height as u32, + let image: Image = Image { + buffer: locked.as_slice(), + width: width as u32, + height: height as u32, - stride: (stride * 4u64) as u32, // I think? - format: turbojpeg_sys::TJPF_TJPF_RGBA, - }; + stride: (stride * 4u64) as u32, // I think? + format: turbojpeg_sys::TJPF_TJPF_RGBA, + }; - let vec = COMPRESSOR.with(|lazy| { - let mut b = lazy.borrow_mut(); - b.set_quality(35); - b.set_subsamp(turbojpeg_sys::TJSAMP_TJSAMP_420); - b.compress_buffer(&image) - }); + let vec = COMPRESSOR.with(|lazy| { + let mut b = lazy.borrow_mut(); + b.set_quality(35); + b.set_subsamp(turbojpeg_sys::TJSAMP_TJSAMP_420); + b.compress_buffer(&image) + }); - // Fulfill the Javascript promise with our encoded buffer - deferred.settle_with(&channel, move |mut cx| { - let mut buf = cx.buffer(vec.len())?; - let slice = buf.as_mut_slice(&mut cx); - slice.copy_from_slice(vec.as_slice()); - Ok(buf) - }); - }); + // Fulfill the Javascript promise with our encoded buffer + deferred.settle_with(&channel, move |mut cx| { + let mut buf = cx.buffer(vec.len())?; + let slice = buf.as_mut_slice(&mut cx); + slice.copy_from_slice(vec.as_slice()); + Ok(buf) + }); + }); - Ok(promise) + Ok(promise) } pub fn jpeg_encode(mut cx: FunctionContext) -> JsResult { - jpeg_encode_impl(&mut cx) + jpeg_encode_impl(&mut cx) } diff --git a/cvm-rs/src/lib.rs b/cvm-rs/src/lib.rs index 39f4bbd..b96db56 100644 --- a/cvm-rs/src/lib.rs +++ b/cvm-rs/src/lib.rs @@ -8,10 +8,10 @@ use neon::prelude::*; #[neon::main] fn main(mut cx: ModuleContext) -> NeonResult<()> { - // Mostly transitionary, later on API should change - cx.export_function("jpegEncode", jpeg_js::jpeg_encode)?; + // Mostly transitionary, later on API should change + cx.export_function("jpegEncode", jpeg_js::jpeg_encode)?; - cx.export_function("guacDecode", guac_js::guac_decode)?; - cx.export_function("guacEncode", guac_js::guac_encode)?; - Ok(()) + cx.export_function("guacDecode", guac_js::guac_decode)?; + cx.export_function("guacEncode", guac_js::guac_encode)?; + Ok(()) }