Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds encased String #15

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ panic = 'abort'

[features]
random = ["rand"]
encased = []

[dependencies]
rand = { version = "^0.7", optional = true }
Expand Down
23 changes: 23 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::{env, fs, path::Path};

fn main() {
let encased = env::var_os("CARGO_FEATURE_ENCASED").is_some();
let out_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let lib_path = Path::new(&out_dir).join("src/lib.rs");

let content = fs::read_to_string(lib_path.clone()).unwrap();

let new_content = if encased {
content.replace(
"//ADT_CONST_PARAMS_REPLACE",
"#![feature(adt_const_params)]",
)
} else {
content.replace(
"#![feature(adt_const_params)]",
"//ADT_CONST_PARAMS_REPLACE",
)
};

fs::write(&lib_path, new_content).unwrap();
}
4 changes: 4 additions & 0 deletions src/case.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[cfg(feature = "encased")]
use std::marker::ConstParamTy;

#[cfg(test)]
use strum_macros::EnumIter;

Expand All @@ -24,6 +27,7 @@ use crate::Boundary;
/// camel case identifier `myVarName` is split where a lowercase letter is followed by an
/// uppercase letter. Each case is also associated with a list of boundaries that are used when
/// converting "from" a particular case.
#[cfg_attr(feature = "encased", derive(ConstParamTy))]
#[cfg_attr(test, derive(EnumIter))]
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
pub enum Case {
Expand Down
24 changes: 24 additions & 0 deletions src/encased.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![cfg(feature = "encased")]
use crate::{Case, Casing};

#[derive(Eq, PartialEq, Hash, Clone, Debug)]
pub struct Encased<const CASE: Case>(String);

impl<const C: Case> Encased<C> {
pub fn new<const CASE: Case, T: AsRef<str> + Sized>(input: &T) -> Encased<CASE>
where
String: PartialEq<T>,
{
Encased::<CASE>(input.to_case(CASE))
}

pub fn raw(&self) -> &String {
&self.0
}
}

impl<const C: Case> ToString for Encased<C>{
fn to_string(&self) -> String {
self.raw().clone()
}
}
26 changes: 20 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
//! # Command Line Utility `ccase`
//!
//! This library was developed for the purposes of a command line utility for converting
//! the case of strings and filenames. You can check out
//! the case of strings and filenames. You can check out
//! [`ccase` on Github](https://github.com/rutrum/ccase).
//!
//! # Rust Library
//!
//! Provides a [`Case`](enum.Case.html) enum which defines a variety of cases to convert into.
//! Strings have implemented the [`Casing`](trait.Casing.html) trait, which adds methods for
//! Strings have implemented the [`Casing`](trait.Casing.html) trait, which adds methods for
//! case conversion.
//!
//! You can convert strings into a case using the [`to_case`](Casing::to_case) method.
Expand Down Expand Up @@ -45,7 +45,7 @@
//! );
//! ```
//!
//! Case conversion can detect acronyms for camel-like strings. It also ignores any leading,
//! Case conversion can detect acronyms for camel-like strings. It also ignores any leading,
//! trailing, or duplicate delimiters.
//! ```
//! use convert_case::{Case, Casing};
Expand Down Expand Up @@ -171,7 +171,7 @@
//! conv.convert("My Special Case")
//! )
//! ```
//! Just as with the `Casing` trait, you can also manually set the boundaries strings are split
//! Just as with the `Casing` trait, you can also manually set the boundaries strings are split
//! on. You can use any of the [`Pattern`] variants available. This even includes [`Pattern::Sentence`]
//! which isn't used in any `Case` variant. You can also set no pattern at all, which will
//! maintain the casing of each letter in the input string. You can also, of course, set any string as your
Expand All @@ -191,13 +191,19 @@
//! This will add two additional cases: Random and PseudoRandom. You can read about their
//! construction in the [Case enum](enum.Case.html).

//ADT_CONST_PARAMS_REPLACE

mod case;
mod converter;
#[cfg(feature = "encased")]
mod encased;
mod pattern;
mod segmentation;

pub use case::Case;
pub use converter::Converter;
#[cfg(feature = "encased")]
pub use encased::Encased;
pub use pattern::Pattern;
pub use segmentation::Boundary;

Expand All @@ -207,7 +213,6 @@ pub use segmentation::Boundary;
///
/// Implemented for strings `&str`, `String`, and `&String`.
pub trait Casing<T: AsRef<str>> {

/// Convert the string into the given case. It will reference `self` and create a new
/// `String` with the same pattern and delimeter as `case`. It will split on boundaries
/// defined at [`Boundary::defaults()`].
Expand Down Expand Up @@ -253,14 +258,23 @@ pub trait Casing<T: AsRef<str>> {
/// the conversion and seeing if the result is the same.
/// ```
/// use convert_case::{Case, Casing};
///
///
/// assert!( "kebab-case-string".is_case(Case::Kebab));
/// assert!( "Train-Case-String".is_case(Case::Train));
///
/// assert!(!"kebab-case-string".is_case(Case::Snake));
/// assert!(!"kebab-case-string".is_case(Case::Train));
/// ```
fn is_case(&self, case: Case) -> bool;

#[cfg(feature = "encased")]
fn encased<const CASE: Case>(&self) -> Encased<CASE>
where
Self: AsRef<str> + Sized,
String: PartialEq<Self>,
{
Encased::<CASE>::new::<CASE, Self>(&self)
}
}

impl<T: AsRef<str>> Casing<T> for T
Expand Down
29 changes: 29 additions & 0 deletions tests/encased.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#![cfg(feature = "encased")]

use convert_case::{Case, Casing};
#[test]
fn encased_string_type() {
let s: String = String::from("rust_programming_language");
assert_eq!(
"RustProgrammingLanguage",
s.encased::<{ Case::Pascal }>().raw(),
);
}

#[test]
fn encased_str_type() {
let s: &str = "rust_programming_language";
assert_eq!(
"RustProgrammingLanguage",
s.encased::<{ Case::Pascal }>().raw(),
);
}

#[test]
fn encased_string_ref_type() {
let s: String = String::from("rust_programming_language");
assert_eq!(
"RustProgrammingLanguage",
(&s).encased::<{ Case::Pascal }>().raw(),
);
}