-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stdlib): add casing functions (#973)
* feat(stdlib): add casing functions * feat(stdlib): add fns to bench * feat(stdlib): fix test * feat(stdlib): add LICENSE
- Loading branch information
Showing
12 changed files
with
661 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ combine,https://github.com/Marwes/combine,MIT,Markus Westerlind <marwes91@gmail. | |
community-id,https://github.com/traceflight/rs-community-id,MIT OR Apache-2.0,Julian Wang <[email protected]> | ||
concurrent-queue,https://github.com/smol-rs/concurrent-queue,Apache-2.0 OR MIT,"Stjepan Glavina <[email protected]>, Taiki Endo <[email protected]>, John Nunley <[email protected]>" | ||
convert_case,https://github.com/rutrum/convert-case,MIT,David Purdum <[email protected]> | ||
convert_case,https://github.com/rutrum/convert-case,MIT,Rutrum <[email protected]> | ||
core-foundation,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers | ||
cpufeatures,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers | ||
crc32fast,https://github.com/srijs/rust-crc32fast,MIT OR Apache-2.0,"Sam Rijs <[email protected]>, Alex Crichton <[email protected]>" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
added casing functions `camelcase`, `kebabcase`, `screamingsnakecase`, `snakecase`, `pascalcase` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use crate::compiler::prelude::*; | ||
|
||
use convert_case::Case; | ||
|
||
fn camelcase(value: Value, orig_case: Option<Case>) -> Resolved { | ||
super::convert_case(value, Case::Camel, orig_case) | ||
} | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct Camelcase; | ||
|
||
impl Function for Camelcase { | ||
fn identifier(&self) -> &'static str { | ||
"camelcase" | ||
} | ||
|
||
fn parameters(&self) -> &'static [Parameter] { | ||
&[ | ||
Parameter { | ||
keyword: "value", | ||
kind: kind::BYTES, | ||
required: true, | ||
}, | ||
Parameter { | ||
keyword: "original_case", | ||
kind: kind::BYTES, | ||
required: false, | ||
}, | ||
] | ||
} | ||
|
||
fn compile( | ||
&self, | ||
state: &state::TypeState, | ||
_ctx: &mut FunctionCompileContext, | ||
arguments: ArgumentList, | ||
) -> Compiled { | ||
let value = arguments.required("value"); | ||
let original_case = arguments | ||
.optional_enum("original_case", &super::variants(), state)? | ||
.map(|b| { | ||
b.try_bytes_utf8_lossy() | ||
.expect("cant convert to string") | ||
.into_owned() | ||
}) | ||
.map(super::into_case) | ||
.transpose()?; | ||
|
||
Ok(CamelcaseFn { | ||
value, | ||
original_case, | ||
} | ||
.as_expr()) | ||
} | ||
|
||
fn examples(&self) -> &'static [Example] { | ||
&[Example { | ||
title: "camelcase", | ||
source: r#"camelcase("input_string")"#, | ||
result: Ok("inputString"), | ||
}] | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
struct CamelcaseFn { | ||
value: Box<dyn Expression>, | ||
original_case: Option<Case>, | ||
} | ||
|
||
impl FunctionExpression for CamelcaseFn { | ||
fn resolve(&self, ctx: &mut Context) -> Resolved { | ||
let value = self.value.resolve(ctx)?; | ||
let original_case = self.original_case; | ||
camelcase(value, original_case) | ||
} | ||
|
||
fn type_def(&self, _: &state::TypeState) -> TypeDef { | ||
TypeDef::bytes().infallible() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::value; | ||
|
||
test_function![ | ||
camelcase => Camelcase; | ||
|
||
simple { | ||
args: func_args![value: value!("into_camel"), original_case: "snake_case"], | ||
want: Ok(value!("intoCamel")), | ||
tdef: TypeDef::bytes(), | ||
} | ||
|
||
no_case { | ||
args: func_args![value: value!("into_camel")], | ||
want: Ok(value!("intoCamel")), | ||
tdef: TypeDef::bytes(), | ||
} | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use crate::compiler::prelude::*; | ||
|
||
use convert_case::Case; | ||
|
||
fn kebabcase(value: Value, orig_case: Option<Case>) -> Resolved { | ||
super::convert_case(value, Case::Kebab, orig_case) | ||
} | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub struct Kebabcase; | ||
|
||
impl Function for Kebabcase { | ||
fn identifier(&self) -> &'static str { | ||
"kebabcase" | ||
} | ||
|
||
fn parameters(&self) -> &'static [Parameter] { | ||
&[ | ||
Parameter { | ||
keyword: "value", | ||
kind: kind::BYTES, | ||
required: true, | ||
}, | ||
Parameter { | ||
keyword: "original_case", | ||
kind: kind::BYTES, | ||
required: false, | ||
}, | ||
] | ||
} | ||
|
||
fn compile( | ||
&self, | ||
state: &state::TypeState, | ||
_ctx: &mut FunctionCompileContext, | ||
arguments: ArgumentList, | ||
) -> Compiled { | ||
let value = arguments.required("value"); | ||
let original_case = arguments | ||
.optional_enum("original_case", &super::variants(), state)? | ||
.map(|b| { | ||
b.try_bytes_utf8_lossy() | ||
.expect("cant convert to string") | ||
.into_owned() | ||
}) | ||
.map(super::into_case) | ||
.transpose()?; | ||
|
||
Ok(KebabcaseFn { | ||
value, | ||
original_case, | ||
} | ||
.as_expr()) | ||
} | ||
|
||
fn examples(&self) -> &'static [Example] { | ||
&[Example { | ||
title: "kebabcase", | ||
source: r#"kebabcase("input_string")"#, | ||
result: Ok("input-string"), | ||
}] | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
struct KebabcaseFn { | ||
value: Box<dyn Expression>, | ||
original_case: Option<Case>, | ||
} | ||
|
||
impl FunctionExpression for KebabcaseFn { | ||
fn resolve(&self, ctx: &mut Context) -> Resolved { | ||
let value = self.value.resolve(ctx)?; | ||
let original_case = self.original_case; | ||
kebabcase(value, original_case) | ||
} | ||
|
||
fn type_def(&self, _: &state::TypeState) -> TypeDef { | ||
TypeDef::bytes().infallible() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::value; | ||
|
||
test_function![ | ||
kebabcase => Kebabcase; | ||
|
||
simple { | ||
args: func_args![value: value!("input_string"), original_case: "snake_case"], | ||
want: Ok(value!("input-string")), | ||
tdef: TypeDef::bytes(), | ||
} | ||
|
||
no_case { | ||
args: func_args![value: value!("input_string")], | ||
want: Ok(value!("input-string")), | ||
tdef: TypeDef::bytes(), | ||
} | ||
]; | ||
} |
Oops, something went wrong.