git.delta.rocks / jrsonnet / refs/commits / 2e5acc0c12c5

difftreelog

refactor(stdlib) split more builtins into own files

Yaroslav Bolyukin2022-10-17parent: #446308e.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
39pub use manifest::*;39pub use manifest::*;
40mod parse;40mod parse;
41pub use parse::*;41pub use parse::*;
42mod strings;
43pub use strings::*;
44mod misc;
45pub use misc::*;
4246
43pub fn stdlib_uncached(s: State, settings: Rc<RefCell<Settings>>) -> ObjValue {47pub fn stdlib_uncached(s: State, settings: Rc<RefCell<Settings>>) -> ObjValue {
44 let mut builder = ObjValueBuilder::new();48 let mut builder = ObjValueBuilder::new();
52 builder.with_super(eval);56 builder.with_super(eval);
5357
54 for (name, builtin) in [58 for (name, builtin) in [
55 ("length", builtin_length::INST),
56 // Types59 // Types
57 ("type", builtin_type::INST),60 ("type", builtin_type::INST),
58 ("isString", builtin_is_string::INST),61 ("isString", builtin_is_string::INST),
117 // Parsing120 // Parsing
118 ("parseJson", builtin_parse_json::INST),121 ("parseJson", builtin_parse_json::INST),
119 ("parseYaml", builtin_parse_yaml::INST),122 ("parseYaml", builtin_parse_yaml::INST),
120 // Misc123 // Strings
121 ("codepoint", builtin_codepoint::INST),124 ("codepoint", builtin_codepoint::INST),
122 ("substr", builtin_substr::INST),125 ("substr", builtin_substr::INST),
123 ("char", builtin_char::INST),126 ("char", builtin_char::INST),
126 ("asciiUpper", builtin_ascii_upper::INST),129 ("asciiUpper", builtin_ascii_upper::INST),
127 ("asciiLower", builtin_ascii_lower::INST),130 ("asciiLower", builtin_ascii_lower::INST),
128 ("findSubstr", builtin_find_substr::INST),131 ("findSubstr", builtin_find_substr::INST),
132 // Misc
133 ("length", builtin_length::INST),
129 ("startsWith", builtin_starts_with::INST),134 ("startsWith", builtin_starts_with::INST),
130 ("endsWith", builtin_ends_with::INST),135 ("endsWith", builtin_ends_with::INST),
131 ]136 ]
345 }350 }
346}351}
347
348#[builtin]
349fn builtin_length(x: Either![IStr, ArrValue, ObjValue, FuncVal]) -> Result<usize> {
350 use Either4::*;
351 Ok(match x {
352 A(x) => x.chars().count(),
353 B(x) => x.len(),
354 C(x) => x.len(),
355 D(f) => f.params_len(),
356 })
357}
358
359#[builtin]
360const fn builtin_codepoint(str: char) -> Result<u32> {
361 Ok(str as u32)
362}
363
364#[builtin]
365fn builtin_substr(str: IStr, from: usize, len: usize) -> Result<String> {
366 Ok(str.chars().skip(from).take(len).collect())
367}
368
369#[builtin(fields(
370 settings: Rc<RefCell<Settings>>,
371))]
372fn builtin_ext_var(this: &builtin_ext_var, s: State, x: IStr) -> Result<Any> {
373 let ctx = s.create_default_context(extvar_source(&x, ""));
374 Ok(Any(this
375 .settings
376 .borrow()
377 .ext_vars
378 .get(&x)
379 .cloned()
380 .ok_or_else(|| UndefinedExternalVariable(x))?
381 .evaluate_arg(s.clone(), ctx, true)?
382 .evaluate(s)?))
383}
384
385#[builtin(fields(
386 settings: Rc<RefCell<Settings>>,
387))]
388fn builtin_native(this: &builtin_native, name: IStr) -> Result<Any> {
389 Ok(Any(this
390 .settings
391 .borrow()
392 .ext_natives
393 .get(&name)
394 .cloned()
395 .map_or(Val::Null, |v| {
396 Val::Func(FuncVal::Builtin(v.clone()))
397 })))
398}
399
400#[builtin]
401fn builtin_char(n: u32) -> Result<char> {
402 Ok(std::char::from_u32(n).ok_or_else(|| InvalidUnicodeCodepointGot(n))?)
403}
404
405#[builtin(fields(
406 settings: Rc<RefCell<Settings>>,
407))]
408fn builtin_trace(
409 this: &builtin_trace,
410 s: State,
411 loc: CallLocation,
412 str: IStr,
413 rest: Thunk<Val>,
414) -> Result<Any> {
415 this.settings
416 .borrow()
417 .trace_printer
418 .print_trace(s.clone(), loc, str);
419 Ok(Any(rest.evaluate(s)?))
420}
421
422#[builtin]
423fn builtin_str_replace(str: String, from: IStr, to: IStr) -> Result<String> {
424 Ok(str.replace(&from as &str, &to as &str))
425}
426
427#[builtin]
428fn builtin_splitlimit(str: IStr, c: IStr, maxsplits: Either![usize, M1]) -> Result<VecVal> {
429 use Either2::*;
430 Ok(VecVal(Cc::new(match maxsplits {
431 A(n) => str
432 .splitn(n + 1, &c as &str)
433 .map(|s| Val::Str(s.into()))
434 .collect(),
435 B(_) => str.split(&c as &str).map(|s| Val::Str(s.into())).collect(),
436 })))
437}
438
439#[builtin]
440fn builtin_ascii_upper(str: IStr) -> Result<String> {
441 Ok(str.to_ascii_uppercase())
442}
443
444#[builtin]
445fn builtin_ascii_lower(str: IStr) -> Result<String> {
446 Ok(str.to_ascii_lowercase())
447}
448
449#[builtin]
450fn builtin_find_substr(pat: IStr, str: IStr) -> Result<ArrValue> {
451 if pat.is_empty() || str.is_empty() || pat.len() > str.len() {
452 return Ok(ArrValue::empty());
453 }
454
455 let str = str.as_str();
456 let pat = pat.as_bytes();
457 let strb = str.as_bytes();
458
459 let max_pos = str.len() - pat.len();
460
461 let mut out: Vec<Val> = Vec::new();
462 for (ch_idx, (i, _)) in str
463 .char_indices()
464 .take_while(|(i, _)| i <= &max_pos)
465 .enumerate()
466 {
467 if &strb[i..i + pat.len()] == pat {
468 out.push(Val::Num(ch_idx as f64))
469 }
470 }
471 Ok(out.into())
472}
473
474#[allow(clippy::comparison_chain)]
475#[builtin]
476fn builtin_starts_with(
477 s: State,
478 a: Either![IStr, ArrValue],
479 b: Either![IStr, ArrValue],
480) -> Result<bool> {
481 Ok(match (a, b) {
482 (Either2::A(a), Either2::A(b)) => a.starts_with(b.as_str()),
483 (Either2::B(a), Either2::B(b)) => {
484 if b.len() > a.len() {
485 return Ok(false);
486 } else if b.len() == a.len() {
487 return equals(s, &Val::Arr(a), &Val::Arr(b));
488 } else {
489 for (a, b) in a
490 .slice(None, Some(b.len()), None)
491 .iter(s.clone())
492 .zip(b.iter(s.clone()))
493 {
494 let a = a?;
495 let b = b?;
496 if !equals(s.clone(), &a, &b)? {
497 return Ok(false);
498 }
499 }
500 true
501 }
502 }
503 _ => throw!("both arguments should be of the same type"),
504 })
505}
506
507#[allow(clippy::comparison_chain)]
508#[builtin]
509fn builtin_ends_with(
510 s: State,
511 a: Either![IStr, ArrValue],
512 b: Either![IStr, ArrValue],
513) -> Result<bool> {
514 Ok(match (a, b) {
515 (Either2::A(a), Either2::A(b)) => a.ends_with(b.as_str()),
516 (Either2::B(a), Either2::B(b)) => {
517 if b.len() > a.len() {
518 return Ok(false);
519 } else if b.len() == a.len() {
520 return equals(s, &Val::Arr(a), &Val::Arr(b));
521 } else {
522 let a_len = a.len();
523 for (a, b) in a
524 .slice(Some(a_len - b.len()), None, None)
525 .iter(s.clone())
526 .zip(b.iter(s.clone()))
527 {
528 let a = a?;
529 let b = b?;
530 if !equals(s.clone(), &a, &b)? {
531 return Ok(false);
532 }
533 }
534 true
535 }
536 }
537 _ => throw!("both arguments should be of the same type"),
538 })
539}
540352
541pub trait StateExt {353pub trait StateExt {
542 /// This method was previously implemented in jrsonnet-evaluator itself354 /// This method was previously implemented in jrsonnet-evaluator itself
addedcrates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth

no changes

addedcrates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth

no changes