rscel 1.0.8

Cel interpreter in rust
Documentation
use rscel_macro::dispatch;

pub use methods::dispatch as slice;

#[dispatch]
mod methods {
    use crate::CelValue;

    fn slice(this: Vec<CelValue>, start: i64, end: i64) -> CelValue {
        internal::slice(this, start as isize, end as isize)
    }

    fn slice(this: Vec<CelValue>, start: u64, end: u64) -> CelValue {
        internal::slice(this, start as isize, end as isize)
    }

    fn slice(this: Vec<CelValue>, start: i64, end: u64) -> CelValue {
        internal::slice(this, start as isize, end as isize)
    }

    fn slice(this: Vec<CelValue>, start: u64, end: i64) -> CelValue {
        internal::slice(this, start as isize, end as isize)
    }

    mod internal {
        use crate::{CelError, CelValue};

        pub fn slice(this: Vec<CelValue>, start: isize, end: isize) -> CelValue {
            let len = this.len() as isize;

            let resolve = |idx: isize| -> isize {
                if idx < 0 {
                    (len + idx).max(0)
                } else {
                    idx.min(len)
                }
            };

            let start = resolve(start) as usize;
            let end = resolve(end) as usize;

            if start > end {
                return CelValue::from_err(CelError::argument(
                    "slice() start index must be <= end index",
                ));
            }

            this.into_iter().skip(start).take(end - start).collect::<Vec<_>>().into()
        }
    }
}