Skip to content

Commit

Permalink
Final touches on documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rutrum committed Jan 12, 2025
1 parent a2101e1 commit ae4b79e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 13 deletions.
26 changes: 16 additions & 10 deletions src/boundary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ fn grapheme_is_lowercase(c: &&str) -> bool {
c.to_uppercase() != c.to_lowercase() && *c == c.to_lowercase()
}

/// A boundary defines how an identifier is split into words. Some boundaries, `HYPHEN`,
/// `UNDERSCORE`, and `SPACE`, consume the character they split on, whereas the other boundaries
/// do not.
/// How an identifier is split into words.
///
/// Some boundaries, `HYPHEN`, `UNDERSCORE`, and `SPACE`, consume the character they
/// split on, whereas the other boundaries do not.
///
/// `Boundary` includes methods that return useful groups of boundaries. It also
/// contains the [`defaults_from`](Boundary::defaults_from) method which will generate a subset
Expand Down Expand Up @@ -46,7 +47,7 @@ pub struct Boundary {
/// of the string. Second argument is the `arg` field.
pub condition: fn(&[&str], Option<&'static str>) -> bool,
/// An optional string passed to `condition` at runtime. Used
/// internally for `from_delim`` method.
/// internally for [`Boundary::from_delim`] method.
pub arg: Option<&'static str>,
/// Where the beginning of the boundary is.
pub start: usize,
Expand Down Expand Up @@ -396,12 +397,17 @@ impl Boundary {
}
}

// another idea for this algorithm
// build an array of integers where
// 0 means no split
// 1 means the split is left of this char
// 2 means this character is removed
// then I can build the word at the end
/// Split an identifier into a list of words using the list of boundaries.
///
/// This is used internally for splitting an identifier before mutating by
/// a pattern and joining again with a delimiter.
/// ```
/// use convert_case::{Boundary, split};
/// assert_eq!(
/// vec!["one", "two", "three.four"],
/// split(&"one_two-three.four", &[Boundary::UNDERSCORE, Boundary::HYPHEN]),
/// )
/// ```
pub fn split<'s, T>(s: &'s T, boundaries: &[Boundary]) -> Vec<&'s str>
where
T: AsRef<str>,
Expand Down
47 changes: 44 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@
//! provides the [`from_case`](Casing::from_case) functionality, but sometimes that isn't enough
//! to meet a specific use case.
//!
//! Take an identifier has the word `2D`, such as `scale2D`. No exclusive usage of `from_case` will
//! Say an identifier has the word `2D`, such as `scale2D`. No exclusive usage of `from_case` will
//! be enough to solve the problem. In this case we can further specify which boundaries to split
//! the string on. `convert_case` provides some patterns for achieving this specificity.
//! We can specify what boundaries we want to split on using the [`Boundary` enum](Boundary).
//! We can specify what boundaries we want to split on using instances the [`Boundary` struct](Boundary).
//! ```
//! use convert_case::{Boundary, Case, Casing};
//!
Expand Down Expand Up @@ -144,6 +144,47 @@
//! The `Casing` trait provides initial methods, but any subsequent methods that do not resolve
//! the conversion return a [`StateConverter`] struct. It contains similar methods as `Casing`.
//!
//! ## Custom Boundaries
//!
//! `convert_case` provides a number of constants for boundaries associated with common cases.
//! But you can create your own boundary to split on other criteria. For simple, delimiter
//! based splits, use [`Boundary::from_delim`].
//!
//! ```
//! # use convert_case::{Boundary, Case, Casing};
//! assert_eq!(
//! "Coolers Revenge",
//! "coolers.revenge"
//! .with_boundaries(&[Boundary::from_delim(".")])
//! .to_case(Case::Title)
//! )
//! ```
//!
//! For more complex boundaries, such as splitting based on the first character being a certain
//! symbol and the second is lowercase, you can instantiate a boundary directly.
//!
//! ```
//! # use convert_case::{Boundary, Case, Casing};
//! let at_then_letter = Boundary {
//! name: "AtLetter",
//! condition: |s, _| {
//! s.get(0).map(|c| *c == "@") == Some(true)
//! && s.get(1).map(|c| *c == c.to_lowercase()) == Some(true)
//! },
//! arg: None,
//! start: 1,
//! len: 0,
//! };
//! assert_eq!(
//! "Name@ Domain",
//! "name@domain"
//! .with_boundaries(&[at_then_letter])
//! .to_case(Case::Title)
//! )
//! ```
//!
//! To learn more about building a boundary from scratch, read the [`Boundary`] struct.
//!
//! # Custom Cases
//!
//! Because `Case` is an enum, you can't create your own variant for your use case. However
Expand Down Expand Up @@ -191,7 +232,7 @@ mod case;
mod converter;
mod pattern;

pub use boundary::Boundary;
pub use boundary::{split, Boundary};
pub use case::Case;
pub use converter::Converter;
pub use pattern::Pattern;
Expand Down

0 comments on commit ae4b79e

Please sign in to comment.