Skip to content

Commit

Permalink
Merge pull request #31 from alerque/mlua-v010
Browse files Browse the repository at this point in the history
Update to mlua v0.10 and overhaul Lua module creation
  • Loading branch information
alerque authored Oct 25, 2024
2 parents d80f120 + 369d139 commit 9ef0dd1
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 110 deletions.
22 changes: 15 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,18 @@ strum = "0.26"
strum_macros = "0.26"
unicode_titlecase = "2.3"

[dependencies.anyhow]
version = "1.0"

[dependencies.clap]
version = "4.5"
optional = true
features = ["derive", "wrap_help"]

[dependencies.mlua]
version = "0.9"
version = "0.10.0"
optional = true
features = ["module"]
features = ["module", "anyhow"]

[dependencies.pyo3]
version = "0.22"
Expand Down
6 changes: 3 additions & 3 deletions src/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::types::Result;
use regex::Regex;
use std::{borrow::Cow, error, fmt, fmt::Display, str::FromStr};
use std::{borrow::Cow, fmt, fmt::Display, str::FromStr};

#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
Expand All @@ -12,7 +12,7 @@ pub enum Segment {
Word(String),
}

#[derive(Debug, Clone)]
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct Chunk {
pub segments: Vec<Segment>,
Expand Down Expand Up @@ -56,7 +56,7 @@ impl From<&Cow<'_, str>> for Chunk {
}

impl FromStr for Chunk {
type Err = Box<dyn error::Error>;
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
Ok(split_chunk(s))
}
Expand Down
140 changes: 53 additions & 87 deletions src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,102 +8,68 @@ pub use crate::types::{Case, Locale, Result, StyleGuide};

#[mlua::lua_module]
fn decasify(lua: &Lua) -> LuaResult<LuaTable> {
let exports = lua.create_table().unwrap();
let case = lua.create_function(case)?;
exports.set("case", case).unwrap();
let titlecase = lua.create_function(titlecase)?;
exports.set("titlecase", titlecase).unwrap();
let lowercase = lua.create_function(lowercase)?;
exports.set("lowercase", lowercase).unwrap();
let uppercase = lua.create_function(uppercase)?;
exports.set("uppercase", uppercase).unwrap();
let sentencecase = lua.create_function(sentencecase)?;
exports.set("sentencecase", sentencecase).unwrap();
let exports = lua.create_table()?;
exports.set(
"case",
LuaFunction::wrap_raw::<_, (Chunk, Case, Locale, StyleGuide)>(to_case),
)?;
exports.set(
"titlecase",
LuaFunction::wrap_raw::<_, (Chunk, Locale, StyleGuide)>(to_titlecase),
)?;
exports.set(
"lowercase",
LuaFunction::wrap_raw::<_, (Chunk, Locale)>(to_lowercase),
)?;
exports.set(
"uppercase",
LuaFunction::wrap_raw::<_, (Chunk, Locale)>(to_uppercase),
)?;
exports.set(
"sentencecase",
LuaFunction::wrap_raw::<_, (Chunk, Locale)>(to_sentencecase),
)?;
let version = option_env!("VERGEN_GIT_DESCRIBE").unwrap_or_else(|| env!("CARGO_PKG_VERSION"));
let version = lua.create_string(version)?;
exports.set("version", version).unwrap();
exports.set("version", version)?;
Ok(exports)
}

fn case<'a>(
lua: &'a Lua,
(input, case, locale, style): (LuaString<'a>, LuaValue<'a>, LuaValue<'a>, LuaValue<'a>),
) -> LuaResult<LuaString<'a>> {
let input = input.to_string_lossy();
let case: Case = match case {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Case::Title),
_ => Case::Title,
};
let locale: Locale = match locale {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Locale::EN),
_ => Locale::EN,
};
let style: StyleGuide = match style {
LuaValue::String(s) => s
.to_string_lossy()
.parse()
.unwrap_or(StyleGuide::LanguageDefault),
_ => StyleGuide::LanguageDefault,
};
let output = to_case(&input, case, locale, style);
lua.create_string(output)
impl FromLua for Chunk {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value {
LuaValue::String(s) => Ok(s.to_string_lossy().into()),
_ => Ok("".into()),
}
}
}

fn titlecase<'a>(
lua: &'a Lua,
(input, locale, style): (LuaString<'a>, LuaValue<'a>, LuaValue<'a>),
) -> LuaResult<LuaString<'a>> {
let input = input.to_string_lossy();
let locale: Locale = match locale {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Locale::EN),
_ => Locale::EN,
};
let style: StyleGuide = match style {
LuaValue::String(s) => s
.to_string_lossy()
.parse()
.unwrap_or(StyleGuide::LanguageDefault),
_ => StyleGuide::LanguageDefault,
};
let output = to_titlecase(&input, locale, style);
lua.create_string(output)
impl FromLua for Locale {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value {
LuaValue::String(s) => Ok(s.to_string_lossy().into()),
LuaValue::Nil => Ok(Self::default()),
_ => unimplemented!(),
}
}
}

fn lowercase<'a>(
lua: &'a Lua,
(input, locale): (LuaString<'a>, LuaValue<'a>),
) -> LuaResult<LuaString<'a>> {
let input = input.to_string_lossy();
let locale: Locale = match locale {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Locale::EN),
_ => Locale::EN,
};
let output = to_lowercase(&input, locale);
lua.create_string(output)
impl FromLua for Case {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value {
LuaValue::String(s) => Ok(s.to_string_lossy().into()),
LuaValue::Nil => Ok(Self::default()),
_ => unimplemented!(),
}
}
}

fn uppercase<'a>(
lua: &'a Lua,
(input, locale): (LuaString<'a>, LuaValue<'a>),
) -> LuaResult<LuaString<'a>> {
let input = input.to_string_lossy();
let locale: Locale = match locale {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Locale::EN),
_ => Locale::EN,
};
let output = to_uppercase(&input, locale);
lua.create_string(output)
}

fn sentencecase<'a>(
lua: &'a Lua,
(input, locale): (LuaString<'a>, LuaValue<'a>),
) -> LuaResult<LuaString<'a>> {
let input = input.to_string_lossy();
let locale: Locale = match locale {
LuaValue::String(s) => s.to_string_lossy().parse().unwrap_or(Locale::EN),
_ => Locale::EN,
};
let output = to_sentencecase(&input, locale);
lua.create_string(output)
impl FromLua for StyleGuide {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value {
LuaValue::String(s) => Ok(s.to_string_lossy().into()),
LuaValue::Nil => Ok(Self::default()),
_ => unimplemented!(),
}
}
}
22 changes: 11 additions & 11 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: © 2023 Caleb Maclennan <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only

use std::{error, fmt, fmt::Display, result, str::FromStr};
use std::{error, fmt, fmt::Display, str::FromStr};
use strum_macros::{Display, VariantNames};

#[cfg(feature = "pythonmodule")]
Expand All @@ -10,7 +10,7 @@ use pyo3::prelude::*;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;

pub type Result<T> = result::Result<T, Box<dyn error::Error>>;
pub type Result<T> = anyhow::Result<T>;

#[derive(Debug)]
pub struct Error(pub String);
Expand Down Expand Up @@ -70,12 +70,12 @@ pub enum StyleGuide {
}

impl FromStr for Locale {
type Err = Box<dyn error::Error>;
fn from_str(s: &str) -> Result<Self> {
type Err = anyhow::Error;
fn from_str(s: &str) -> crate::Result<Self> {
match s.to_ascii_lowercase().as_str() {
"en" | "English" | "en_en" => Ok(Locale::EN),
"tr" | "Turkish" | "tr_tr" | "türkçe" => Ok(Locale::TR),
_ => Err(Box::new(Error("Invalid input language".into()))),
_ => Err(anyhow::Error::new(Error("Invalid input language".into()))),
}
}
}
Expand All @@ -99,14 +99,14 @@ impl From<&String> for Locale {
}

impl FromStr for Case {
type Err = Box<dyn error::Error>;
fn from_str(s: &str) -> Result<Self> {
type Err = anyhow::Error;
fn from_str(s: &str) -> crate::Result<Self> {
match s.to_ascii_lowercase().as_str().trim_end_matches("case") {
"lower" => Ok(Case::Lower),
"sentence" => Ok(Case::Sentence),
"title" => Ok(Case::Title),
"upper" => Ok(Case::Upper),
_ => Err(Box::new(Error("Unknown target case".into()))),
_ => Err(anyhow::Error::new(Error("Unknown target case".into()))),
}
}
}
Expand All @@ -130,8 +130,8 @@ impl From<&String> for Case {
}

impl FromStr for StyleGuide {
type Err = Box<dyn error::Error>;
fn from_str(s: &str) -> Result<Self> {
type Err = anyhow::Error;
fn from_str(s: &str) -> crate::Result<Self> {
match s.to_ascii_lowercase().as_str() {
"daringfireball" | "gruber" | "fireball" => Ok(StyleGuide::DaringFireball),
"associatedpress" | "ap" => Ok(StyleGuide::AssociatedPress),
Expand All @@ -140,7 +140,7 @@ impl FromStr for StyleGuide {
"default" | "languagedefault" | "language" | "none" | "" => {
Ok(StyleGuide::LanguageDefault)
}
_ => Err(Box::new(Error("Invalid style guide".into()))),
_ => Err(anyhow::Error::new(Error("Invalid style guide".into()))),
}
}
}
Expand Down

0 comments on commit 9ef0dd1

Please sign in to comment.