add string split method
This commit is contained in:
parent
7438b2c9e5
commit
6961fcc9fa
4 changed files with 90 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "relish"
|
||||
version = "0.1.0"
|
||||
authors = ["Aidan <aidan@aidanis.online>"]
|
||||
authors = ["Ava <ava@sunnypup.io>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
@ -9,4 +9,3 @@ edition = "2018"
|
|||
[dependencies]
|
||||
dirs = "3.0"
|
||||
rustyline = "8.2.0"
|
||||
once_cell = "1.17.1"
|
||||
11
src/stl.rs
11
src/stl.rs
|
|
@ -74,6 +74,17 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
|
|||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"split".to_string(),
|
||||
Symbol {
|
||||
name: String::from("split"),
|
||||
args: Args::Strict(vec![Type::String, Type::String]),
|
||||
conditional_branches: false,
|
||||
docs: strings::SPLIT_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(strings::split_callback)),
|
||||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"strlen".to_string(),
|
||||
Symbol {
|
||||
|
|
|
|||
|
|
@ -115,3 +115,36 @@ pub fn contains_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String>
|
|||
|
||||
Ok(Ctr::Bool(parent_str.contains(&child_str)))
|
||||
}
|
||||
|
||||
pub const SPLIT_DOCSTRING: &str = "Takes two strings. String 1 is a source string and string 2 is a delimiter.
|
||||
Returns a list of substrings from string 1 that were found delimited by string 2.";
|
||||
|
||||
pub fn split_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
let parent_str: String;
|
||||
if let Ctr::String(ref s) = *ast.car {
|
||||
parent_str = s.to_string();
|
||||
} else {
|
||||
return Err("first argument must be a string".to_string());
|
||||
}
|
||||
|
||||
let second_arg_obj: &Ctr;
|
||||
let delim_str: String;
|
||||
if let Ctr::Seg(ref s) = *ast.cdr {
|
||||
second_arg_obj = &*s.car;
|
||||
} else {
|
||||
return Err("impossible error: needs two arguments".to_string());
|
||||
}
|
||||
|
||||
if let Ctr::String(ref s) = &*second_arg_obj {
|
||||
delim_str = s.clone();
|
||||
} else {
|
||||
return Err("second argument must be a string".to_string());
|
||||
}
|
||||
|
||||
let mut ret = Seg::new();
|
||||
for substr in parent_str.split(&delim_str) {
|
||||
ret.append(Box::new(Ctr::String(substr.to_string())));
|
||||
}
|
||||
|
||||
Ok(Ctr::Seg(ret))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,4 +181,49 @@ mod str_lib_tests {
|
|||
result.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split() {
|
||||
let document = "(split 'one.two.three' '.')";
|
||||
let result = "('one' 'two' 'three')";
|
||||
let mut syms = SymTable::new();
|
||||
static_stdlib(&mut syms).unwrap();
|
||||
dynamic_stdlib(&mut syms).unwrap();
|
||||
assert_eq!(
|
||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
result.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_big_delim() {
|
||||
let document = "(split 'one:d:two:d:three' ':d:')";
|
||||
let result = "('one' 'two' 'three')";
|
||||
let mut syms = SymTable::new();
|
||||
static_stdlib(&mut syms).unwrap();
|
||||
dynamic_stdlib(&mut syms).unwrap();
|
||||
assert_eq!(
|
||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
result.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitnt() {
|
||||
let document = "(split 'one.two.three' '-')";
|
||||
let result = "('one.two.three')";
|
||||
let mut syms = SymTable::new();
|
||||
static_stdlib(&mut syms).unwrap();
|
||||
dynamic_stdlib(&mut syms).unwrap();
|
||||
assert_eq!(
|
||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
result.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue