Skip to content

Commit

Permalink
Fully refactored the code to make it more rusty!
Browse files Browse the repository at this point in the history
versions before 1.3.0 were mostly a rewrite of python library in rust, but in this version I tried to make it more rusty, it still can be a lot better, but its a job for other times.
- we now store all different forms of a letter as a single character instead of old `&'static str` so thats a plus, although I used `\0` for showing empty character, we still have to see how it'll work out.
- fully changed how `letters` work.
- create a new module named `form` to store all the code related to form that is shared between different modules. we use enum now instead of const variables!
- updated ligatures.
- updated reshaper to use the new changes.
- moved test outside of crate.
  • Loading branch information
YouKnow-sys committed Oct 14, 2023
1 parent 76853f7 commit 7ccd659
Show file tree
Hide file tree
Showing 12 changed files with 1,495 additions and 998 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ar-reshaper"
version = "1.1.0"
version = "1.3.0"
authors = ["Saeid Ghafari <saeid025@yahoo.com>"]
edition = "2021"
description = "Reconstruct Arabic sentences to be used in applications that don't support Arabic script."
Expand Down
36 changes: 29 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{letters::LettersType, ligatures::*, ArabicReshaper};
use crate::{form::LettersType, ligatures::*, ArabicReshaper};

/// Flags to enable some or all groups of ligatures
#[derive(Default, Clone, Copy)]
Expand Down Expand Up @@ -46,6 +46,7 @@ pub enum Language {
/// work with both unicode and classic Arabic-Kurdish keybouard
Kurdish,
/// Custom language
#[cfg_attr(feature = "serde", serde(skip))] // we can't serialize this
Custom(&'static [LettersType]),
}

Expand All @@ -61,6 +62,27 @@ impl std::fmt::Display for Language {
}
}

/// Hold state of whatever some ligatures are enabled or not.
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Ligatures {
pub(crate) vec: Vec<bool>,
}

impl Ligatures {
fn new(vec: Vec<bool>) -> Self {
Self { vec }
}

fn is_any_enabled(&self) -> bool {
self.vec.iter().any(|enabled| *enabled)
}

pub fn is_ligature_enabled(&self, name: LigatureNames) -> bool {
self.vec[name as usize]
}
}

/// The main Config struct for the [ArabicReshaper]
///
/// You can change all kinds of settings about [ArabicReshaper] using this struct.
Expand Down Expand Up @@ -88,7 +110,7 @@ pub struct ReshaperConfig {
/// Separate ligatures configuration take precedence over it.
/// When `support_ligatures` is disabled,
/// separate ligatures configurations are ignored.
pub(crate) ligatures: Vec<bool>,
pub ligatures: Ligatures,
}

impl Default for ReshaperConfig {
Expand All @@ -113,7 +135,7 @@ impl Default for ReshaperConfig {
support_zwj: true,
use_unshaped_instead_of_isolated: false,
support_ligatures: true,
ligatures,
ligatures: Ligatures::new(ligatures),
}
}
}
Expand Down Expand Up @@ -146,7 +168,7 @@ impl ReshaperConfig {
Self {
language,
support_ligatures: !ligatures_flags.is_none_enabled(),
ligatures,
ligatures: Ligatures::new(ligatures),
..Default::default()
}
}
Expand Down Expand Up @@ -239,9 +261,9 @@ impl ReshaperConfig {
}

/// Update the given [LigatureNames].
pub fn update_ligature(&mut self, key: LigatureNames, enable: bool) {
self.ligatures[key as usize] = enable;
pub fn update_ligature(&mut self, name: LigatureNames, enable: bool) {
self.ligatures.vec[name as usize] = enable;
// enable or disable ligatures if anything is enabled
self.support_ligatures = self.ligatures.iter().any(|enabled| *enabled);
self.support_ligatures = self.ligatures.is_any_enabled();
}
}
45 changes: 45 additions & 0 deletions src/form.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/// Type of letters
pub type LettersType = (char, Forms);

/// Form of the letter
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(usize)]
pub(crate) enum LetterForm {
Isolated,
Initial,
Medial,
Final,
Unsupported,
Unshaped,
}

/// The main type used to show letter form in each position
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Forms {
pub isolated: char,
pub initial: char,
pub medial: char,
pub end: char,
}

impl Forms {
pub const fn new(isolated: char, initial: char, medial: char, end: char) -> Self {
Self {
isolated,
initial,
medial,
end,
}
}

pub(crate) const fn get(&self, form: LetterForm) -> char {
match form {
LetterForm::Isolated => self.isolated,
LetterForm::Initial => self.initial,
LetterForm::Medial => self.medial,
LetterForm::Final => self.end,
_ => panic!("Unsupported Letter form"),
}
}
}
Loading

0 comments on commit 7ccd659

Please sign in to comment.