From f41b54b649966c81e0769eadb1bb42e957b46949 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 | 163 +++++++++++++++++++++++++++++++++++++++ src/convert/mod.rs | 3 + 2 files changed, 166 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..73b6992 --- /dev/null +++ b/src/convert/eye_shape.rs @@ -0,0 +1,163 @@ +/// 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!("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`] +#[repr(C)] +#[wasm_bindgen] +#[cfg(feature = "wasm-bindgen")] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] +pub enum EyeFrameShape { + /// Square shape + Square, + /// Rounded square shape + Rounded, + /// Circle shape + Circle, + /// Rounded square shape with the outer corner rounded + RoundedSquaredOuterCorner, + /// Leaf shape + Leaf, + /// Rounded square shape with all but the inner corner rounded + RoundedSquaredInnerCorner, + /// Square shape with a dot in the middle + DottedSquare, + /// Eye lash shape + EyeLash, +} + +/// Different possible Shapes to represent modules in a [`crate::QRCode`] +#[cfg(not(feature = "wasm-bindgen"))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] +pub enum EyeFrameShape { + /// Square shape + Square, + /// Rounded square shape + Rounded, + /// Circle shape + Circle, + /// Rounded square shape with the outer corner rounded + RoundedSquaredOuterCorner, + /// Leaf shape + Leaf, + /// Rounded square shape with all but the inner corner rounded + RoundedSquaredInnerCorner, + /// Square shape with a dot in the middle + DottedSquare, + /// Eye lash shape + 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::RoundedSquaredOuterCorner => 3, + EyeFrameShape::Leaf => 4, + EyeFrameShape::RoundedSquaredInnerCorner => 5, + EyeFrameShape::DottedSquare => 6, + EyeFrameShape::EyeLash => 7, + #[cfg(not(target_arch = "wasm32"))] + EyeFrameShape::Command(_) => 8, + } + } +} + +impl From for EyeFrameShape { + #[allow(clippy::match_same_arms)] + fn from(shape: String) -> Self { + match shape.as_ref() { + "square" => Self::Square, + "rounded" => Self::Rounded, + "circle" => Self::Circle, + "rounded_squared_side_1" => Self::RoundedSquaredOuterCorner, + "rounded_squared_side_2" => Self::Leaf, + "rounded_squared_side_3" => Self::RoundedSquaredInnerCorner, + "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::RoundedSquaredOuterCorner => "rounded_squared_side_1", + EyeFrameShape::Leaf => "rounded_squared_side_2", + EyeFrameShape::RoundedSquaredInnerCorner => "rounded_squared_side_3", + EyeFrameShape::DottedSquare => "dotted_square", + EyeFrameShape::EyeLash => "eye_lash", + + #[cfg(not(target_arch = "wasm32"))] + EyeFrameShape::Command(_) => "command", + } + } +} + +impl EyeFrameShape { + pub(crate) fn square(_: EyePosition) -> String { + format!("h7v7h-7") + } + + const FUNCTIONS: [EyeFunction; 1] = [EyeFrameShape::square]; +} + +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 7afd4de..ad0ea48 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::*;