Skip to content

Commit

Permalink
feat: till_needle function
Browse files Browse the repository at this point in the history
  • Loading branch information
ishaan26 committed Oct 2, 2024
1 parent 77f1c70 commit ffccd28
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 5 deletions.
39 changes: 34 additions & 5 deletions zung_mini/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,34 @@ enum MiniCommands {
command: ProgBarCommands,
},

/// Split the provided string on the provided needle.
/// Perform splitting functions over a string.
Strsplit {
#[command(subcommand)]
command: StrsplitCommands,
},
}

#[derive(Clone, Subcommand, Debug)]
#[command(arg_required_else_help = true)]
enum StrsplitCommands {
/// Split the provided string on the provided needle.
Split {
/// The needle to be fond in the haystack.
#[arg(short, long)]
needle: String,

Check warning on line 44 in zung_mini/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

zung_mini/src/lib.rs#L44

Added line #L44 was not covered by tests

/// The haystack to find the needle in.
#[arg(short, long)]
string: String,

Check warning on line 48 in zung_mini/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

zung_mini/src/lib.rs#L48

Added line #L48 was not covered by tests
},

/// Split the provided string until the needle occurs in the String.
Until {
/// The needle to be fond in the haystack.
#[arg(short, long)]
needle: String,

Check warning on line 55 in zung_mini/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

zung_mini/src/lib.rs#L55

Added line #L55 was not covered by tests

/// The haystack to find the needle in.
#[arg(short, long)]
string: String,

Check warning on line 59 in zung_mini/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

zung_mini/src/lib.rs#L59

Added line #L59 was not covered by tests
},
Expand Down Expand Up @@ -99,10 +122,16 @@ impl MiniArgs {
}
}

MiniCommands::Strsplit { needle, string } => {
let result = string.strsplit(&needle).into_vec();
println!("{:?}", result);
}
MiniCommands::Strsplit { command } => match command {
StrsplitCommands::Split { needle, string } => {
let result = string.strsplit(&needle).into_vec();
println!("{:?}", result);
}
StrsplitCommands::Until { needle, string } => {
let result = string.till_needle(needle);
println!("{:?}", result);
}

Check warning on line 133 in zung_mini/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

zung_mini/src/lib.rs#L125-L133

Added lines #L125 - L133 were not covered by tests
},
}
}
}
75 changes: 75 additions & 0 deletions zung_mini/src/strsplit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,32 @@ where
fn strsplit<P>(&'a self, needle: P) -> Strsplit<'a, P>
where
P: 'b + AsRef<str>;

/// Returns the substring before the first occurrence of the given `needle`
/// without scanning the entire string.
///
/// This function splits the string using the provided `needle` and immediately
/// returns the portion of the string before the first occurrence of the `needle`.
/// It stops searching once the `needle` is found, making it efficient as it
/// avoids iterating over the entire string unnecessarily. If the `needle` is not found,
/// the function returns the entire string.
///
/// # Example
///
/// ```rust
/// use zung_mini::strsplit::StrsplitExt;
/// let text = "hello world";
///
/// let result = text.till_needle(" ");
/// assert_eq!(result, "hello");
/// ```
fn till_needle<P>(&'a self, needle: P) -> &str
where
P: 'b + AsRef<str> + Clone,
{
let mut splitter = self.strsplit(needle.clone());
splitter.next().unwrap()
}
}

impl<'a, 'b> StrsplitExt<'a, 'b> for String
Expand Down Expand Up @@ -218,4 +244,53 @@ mod tests {
let a = "a b c, d e f";
assert_eq!(a.strsplit(",").into_vec(), vec!["a b c", " d e f"]);
}

#[test]
fn till_needle_finds_substring() {
let text = "hello world";
let result = text.till_needle(" ");
assert_eq!(result, "hello");
}

#[test]
fn till_needle_returns_entire_string_if_needle_not_found() {
let text = "hello";
let result = text.till_needle(",");
assert_eq!(result, "hello");
}

#[test]
fn till_needle_with_multiple_occurrences() {
let text = "apple,banana,orange";
let result = text.till_needle(",");
assert_eq!(result, "apple"); // Stops at first occurrence
}

#[test]
fn till_needle_returns_none_for_empty_string() {
let text = "";
let result = text.till_needle(",");
assert_eq!(result, "");
}

#[test]
#[should_panic(expected = "Empty needle is not allowed")]
fn till_needle_empty_needle_panics() {
let text = "example";
let _ = text.till_needle(""); // Should panic due to empty needle
}

#[test]
fn till_needle_handles_special_characters() {
let text = "[email protected]";
let result = text.till_needle("@");
assert_eq!(result, "foo");
}

#[test]
fn till_needle_works_with_longer_needle() {
let text = "this is a test string";
let result = text.till_needle("is");
assert_eq!(result, "th");
}
}

0 comments on commit ffccd28

Please sign in to comment.