diff --git a/src/convert/eye_shape.rs b/src/convert/eye_shape.rs
new file mode 100644
index 0000000..cc5b7a0
--- /dev/null
+++ b/src/convert/eye_shape.rs
@@ -0,0 +1,130 @@
+/// 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 {
+ /// 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 => todo!(),
+ EyeFrameShape::Rounded => todo!(),
+ EyeFrameShape::Circle => todo!(),
+ EyeFrameShape::RoundedSquaredSide1 => todo!(),
+ EyeFrameShape::RoundedSquaredSide2 => todo!(),
+ EyeFrameShape::RoundedSquaredSide3 => todo!(),
+ EyeFrameShape::DottedSquare => todo!(),
+ EyeFrameShape::EyeLash => todo!(),
+ #[cfg(not(target_arch = "wasm32"))]
+ EyeFrameShape::Command(_) => 6,
+ }
+ }
+}
+
+impl From for EyeFrameShape {
+ #[allow(clippy::match_same_arms)]
+ fn from(shape: String) -> Self {
+ EyeFrameShape::Command(|_: EyePosition| String::new())
+ }
+}
+
+impl From for &str {
+ fn from(shape: EyeFrameShape) -> Self {
+ match shape {
+ EyeFrameShape::Square => todo!(),
+ EyeFrameShape::Rounded => todo!(),
+ EyeFrameShape::Circle => todo!(),
+ EyeFrameShape::RoundedSquaredSide1 => todo!(),
+ EyeFrameShape::RoundedSquaredSide2 => todo!(),
+ EyeFrameShape::RoundedSquaredSide3 => todo!(),
+ EyeFrameShape::DottedSquare => todo!(),
+ EyeFrameShape::EyeLash => todo!(),
+ #[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 2406654..0b9ca3c 100644
--- a/src/convert/mod.rs
+++ b/src/convert/mod.rs
@@ -19,6 +19,9 @@ pub use color::{rgba2hex, Color, Rgba};
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::*;