[add] modules::time::now

[add] modules::methods::string::replace
[add] modules::methods::string::replacen
[add] modules::methods::string::replaceall
This commit is contained in:
hkau 2024-02-20 22:18:21 -05:00
parent 98ac64d96a
commit 5fade5e530
4 changed files with 182 additions and 14 deletions

View file

@ -1,4 +1,4 @@
use std::time::{SystemTime, UNIX_EPOCH};
use crate::modules::time::unix_epoch_timestamp;
mod config;
mod interpret;
@ -55,12 +55,3 @@ fn main() {
);
}
}
pub fn unix_epoch_timestamp() -> u128 {
let right_now = SystemTime::now();
let time_since = right_now
.duration_since(UNIX_EPOCH)
.expect("Time travel is not allowed");
return time_since.as_millis();
}

View file

@ -26,7 +26,7 @@ pub fn startswith(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
let arg = input.unwrap(); // 'starts_with'
if arg.rule != Rule::string {
error_exit("TYPE", "expected 'starts_with' to be of type string")
error_exit("TYPE", "expected 'starts_with' to be of type 'string'")
}
// ...
@ -67,7 +67,7 @@ pub fn endswith(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
let arg = input.unwrap(); // 'ends_with'
if arg.rule != Rule::string {
error_exit("TYPE", "expected 'ends_with' to be of type string")
error_exit("TYPE", "expected 'ends_with' to be of type 'string'")
}
// ...
@ -615,7 +615,7 @@ pub fn split(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
let arg = args.get(0);
if arg.is_none() | (arg.is_some() && arg.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type string")
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
let do_trim = args.get(1);
@ -657,6 +657,146 @@ pub fn split(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
};
}
/// Replace a sequence in a [`string`](crate::modules::methods::string) input once
///
/// See: <https://docs.python.org/3.8/library/stdtypes.html#str.replace>
pub fn replace(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
// get the object this method is being called on
let fn_self = vars.get("self"); // 'self'
if (fn_self.is_none()) | (fn_self.is_some() && fn_self.unwrap().rule != Rule::string) {
error_exit(
"TYPE",
"expected method to be called on an object with type 'string'",
)
}
// get arguments
let pat = args.get(0);
if pat.is_none() | (pat.is_some() && pat.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
let to = args.get(0);
if to.is_none() | (to.is_some() && to.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
// ...
ReturnValue {
rule: Rule::string,
value: fn_self
.unwrap()
.value
.replace("\"", "")
.replacen(
&pat.unwrap().value.replace("\"", ""),
&to.unwrap().value.replace("\"", ""),
1,
)
.to_string(),
children: Option::None,
attributes: Option::None,
}
}
/// Replace a sequence in a [`string`](crate::modules::methods::string) input `n` times
///
/// See: <https://doc.rust-lang.org/std/string/struct.String.html#method.replacen>
pub fn replacen(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
// get the object this method is being called on
let fn_self = vars.get("self"); // 'self'
if (fn_self.is_none()) | (fn_self.is_some() && fn_self.unwrap().rule != Rule::string) {
error_exit(
"TYPE",
"expected method to be called on an object with type 'string'",
)
}
// get arguments
let pat = args.get(0);
if pat.is_none() | (pat.is_some() && pat.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
let to = args.get(0);
if to.is_none() | (to.is_some() && to.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
let count = args.get(0);
if count.is_none() | (count.is_some() && count.unwrap().rule != Rule::number) {
error_exit("TYPE", "expected 'input' to be of type 'number'")
}
// ...
ReturnValue {
rule: Rule::string,
value: fn_self
.unwrap()
.value
.replace("\"", "")
.replacen(
&pat.unwrap().value.replace("\"", ""),
&to.unwrap().value.replace("\"", ""),
count.unwrap().value.parse::<usize>().unwrap(),
)
.to_string(),
children: Option::None,
attributes: Option::None,
}
}
/// Replace all occurrences of a sequence in a [`string`](crate::modules::methods::string)
///
/// See: <https://doc.rust-lang.org/std/string/struct.String.html#method.replace>
pub fn replaceall(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
// get the object this method is being called on
let fn_self = vars.get("self"); // 'self'
if (fn_self.is_none()) | (fn_self.is_some() && fn_self.unwrap().rule != Rule::string) {
error_exit(
"TYPE",
"expected method to be called on an object with type 'string'",
)
}
// get arguments
let pat = args.get(0);
if pat.is_none() | (pat.is_some() && pat.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
let to = args.get(0);
if to.is_none() | (to.is_some() && to.unwrap().rule != Rule::string) {
error_exit("TYPE", "expected 'input' to be of type 'string'")
}
// ...
ReturnValue {
rule: Rule::string,
value: fn_self
.unwrap()
.value
.replace("\"", "")
.replace(
&pat.unwrap().value.replace("\"", ""),
&to.unwrap().value.replace("\"", ""),
)
.to_string(),
children: Option::None,
attributes: Option::None,
}
}
// ...
/// Import module
pub fn import() -> FunctionsStore {
@ -758,6 +898,21 @@ pub fn import() -> FunctionsStore {
Box::new(|args, vars| split(args, vars)),
);
functions.insert(
String::from("#string::replace"),
Box::new(|args, vars| replace(args, vars)),
);
functions.insert(
String::from("#string::replacen"),
Box::new(|args, vars| replacen(args, vars)),
);
functions.insert(
String::from("#string::replaceall"),
Box::new(|args, vars| replaceall(args, vars)),
);
// return
return functions;
}

View file

@ -28,7 +28,7 @@ pub fn getenv(args: Vec<ReturnValue>) -> ReturnValue {
let arg = input.unwrap();
if arg.rule != Rule::string {
panic!("expected 'time' to be of type string")
panic!("expected 'time' to be of type 'string'")
}
// ...

View file

@ -1,4 +1,5 @@
//! Interpreter time functions, `time:` prefix
use std::time::{SystemTime, UNIX_EPOCH};
use crate::interpret::{FunctionsStore, ReturnValue};
use crate::parser::Rule;
@ -34,6 +35,16 @@ pub fn sleep(args: Vec<ReturnValue>) -> ReturnValue {
};
}
/// Returns the number of milliseconds past the [unix epoch](https://en.wikipedia.org/wiki/Unix_time) it has been
pub fn now() -> ReturnValue {
ReturnValue {
rule: Rule::number,
value: unix_epoch_timestamp().to_string(),
children: Option::None,
attributes: Option::None,
}
}
// ...
/// Import module
pub fn import() -> FunctionsStore {
@ -45,6 +56,17 @@ pub fn import() -> FunctionsStore {
Box::new(|args, _| sleep(args)),
);
functions.insert(String::from("#ST_time_now"), Box::new(|_, _| now()));
// return
return functions;
}
pub fn unix_epoch_timestamp() -> u128 {
let right_now = SystemTime::now();
let time_since = right_now
.duration_since(UNIX_EPOCH)
.expect("Time travel is not allowed");
return time_since.as_millis();
}