From a8e4160780c122d3d3da133e3a9503dc61983908 Mon Sep 17 00:00:00 2001 From: Erwan Vivien Date: Tue, 26 Sep 2023 15:23:35 +0200 Subject: [PATCH] wip: Add different kind of Eye --- src/convert/eye_shape.rs | 148 +++++++++++++++++++++++++++++++++++++++ src/convert/mod.rs | 3 + 2 files changed, 151 insertions(+) create mode 100644 src/convert/eye_shape.rs diff --git a/src/convert/eye_shape.rs b/src/convert/eye_shape.rs new file mode 100644 index 0000000..8eb10da --- /dev/null +++ b/src/convert/eye_shape.rs @@ -0,0 +1,148 @@ +/// Corresponds to the position of the Eye +/// - TopLeft +/// - TopRight +/// - BottomRight +pub enum EyePosition { + /// Top left eye + TopLeft, + /// Top right eye + TopRight, + /// Bottom right eye + BottomRight, +} + +/// Converts an eye position to a custom svg +/// +/// # Example +/// +/// For the fully squared shape, the svg is `M{x},{y}h7v7h-7` +/// +/// The eye function for the eye frame should be max of 7x7. \ +/// The eye function for the eye ball should be max of 3x3. +/// +/// ```rust +/// fn square(_: EyePosition) -> String { +/// format!("M{x},{y}h7v7h-7") +/// } +/// ``` +pub type EyeFunction = fn(EyePosition) -> String; + +// TODO: Find a way to use the same enum for wasm and not wasm +// Current bug being that wasm_bindgen & #[cfg(not(target_arch = "wasm32"))] are not compatible(?) +/// Different possible Shapes to represent modules in a [`crate::QRCode`] +#[cfg(target_arch = "wasm32")] +#[repr(C)] +#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] +pub enum EyeFrameShape { + Square, + Rounded, + Circle, + RoundedSquaredSide1, + RoundedSquaredSide2, + RoundedSquaredSide3, + DottedSquare, + EyeLash, +} + +/// Different possible Shapes to represent modules in a [`crate::QRCode`] +#[cfg(not(target_arch = "wasm32"))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] +pub enum EyeFrameShape { + Square, + Rounded, + Circle, + RoundedSquaredSide1, + RoundedSquaredSide2, + RoundedSquaredSide3, + DottedSquare, + EyeLash, + /// Custom Shape with a function / closure + /// # Example + /// ```rust + /// use fast_qr::convert::EyeFrameShape; + /// let command_function = |eye_position| { + /// match eye_position { + /// EyePosition::TopLeft => String::from("..."), + /// _ => String::from("..."), + /// } + /// }; + /// let command = EyeFrameShape::Command(command_function); + /// ``` + /// + /// + /// + /// + /// + Command(EyeFunction), +} + +impl From for usize { + fn from(shape: EyeFrameShape) -> Self { + match shape { + EyeFrameShape::Square => 0, + EyeFrameShape::Rounded => 1, + EyeFrameShape::Circle => 2, + EyeFrameShape::RoundedSquaredSide1 => 3, + EyeFrameShape::RoundedSquaredSide2 => 4, + EyeFrameShape::RoundedSquaredSide3 => 5, + EyeFrameShape::DottedSquare => 6, + EyeFrameShape::EyeLash => 7, + } + } +} + +impl From for EyeFrameShape { + #[allow(clippy::match_same_arms)] + fn from(shape: String) -> Self { + match &shape { + "square" => Self::Square, + "rounded" => Self::Rounded, + "circle" => Self::Circle, + "rounded_squared_side_1" => Self::RoundedSquaredSide1, + "rounded_squared_side_2" => Self::RoundedSquaredSide2, + "rounded_squared_side_3" => Self::RoundedSquaredSide3, + "dotted_square" => Self::DottedSquare, + "eye_lash" => Self::EyeLash, + + _ => Self::Square, + } + } +} + +impl From for &str { + fn from(shape: EyeFrameShape) -> Self { + match shape { + EyeFrameShape::Square => "square", + EyeFrameShape::Rounded => "rounded", + EyeFrameShape::Circle => "circle", + EyeFrameShape::RoundedSquaredSide1 => "rounded_squared_side_1", + EyeFrameShape::RoundedSquaredSide2 => "rounded_squared_side_2", + EyeFrameShape::RoundedSquaredSide3 => "rounded_squared_side_3", + EyeFrameShape::DottedSquare => "dotted_square", + EyeFrameShape::EyeLash => "eye_lash", + + #[cfg(not(target_arch = "wasm32"))] + EyeFrameShape::Command(_) => "command", + } + } +} + +impl EyeFrameShape { + const FUNCTIONS: [EyeFunction; 0] = []; +} + +impl core::ops::Deref for EyeFrameShape { + type Target = EyeFunction; + + fn deref(&self) -> &Self::Target { + let index: usize = (*self).into(); + match self { + #[cfg(not(target_arch = "wasm32"))] + Self::Command(func) => func, + _ => &Self::FUNCTIONS[index], + } + } +} diff --git a/src/convert/mod.rs b/src/convert/mod.rs index 47fa077..4f74d60 100644 --- a/src/convert/mod.rs +++ b/src/convert/mod.rs @@ -19,6 +19,9 @@ pub use color::{rgba2hex, Color}; mod module_shape; pub use module_shape::{ModuleFunction, ModuleShape}; +mod eye_shape; +pub use eye_shape::{EyeFrameShape, EyeFunction, EyePosition}; + #[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))] use wasm_bindgen::prelude::*;