use super::scan_len;
use crate::{slice::split_at_checked, Parse, ParseResult, SResult};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Script<'a> {
slice: &'a [u8],
from: usize,
}
impl<'a> Parse<'a> for Script<'a> {
#[inline(always)]
fn parse(slice: &'a [u8]) -> SResult<Self> {
let mut consumed = 0;
let n = scan_len(slice, &mut consumed)? as usize;
let (script_bytes, remaining) = split_at_checked(slice, consumed.saturating_add(n))?;
Ok(ParseResult::new(
remaining,
Script {
slice: script_bytes,
from: consumed,
},
))
}
}
impl<'a> Script<'a> {
pub fn script(&self) -> &[u8] {
&self.slice[self.from..]
}
}
impl<'a> AsRef<[u8]> for Script<'a> {
fn as_ref(&self) -> &[u8] {
self.slice
}
}
#[cfg(test)]
mod test {
use crate::{bsl::Script, Error, Parse};
fn check(slice: &[u8], script_slice: &[u8]) {
let script = Script::parse(slice);
assert!(script.is_ok());
let p = script.unwrap();
assert_eq!(p.remaining(), &[]);
assert_eq!(p.parsed().script(), script_slice);
}
#[test]
fn parse_script() {
check(&[1u8, 1], &[1u8]);
check(&[1u8, 11], &[11u8]);
check(&[3u8, 0, 1, 2], &[0u8, 1, 2]);
assert_eq!(Script::parse(&[1u8]), Err(Error::MoreBytesNeeded));
assert_eq!(Script::parse(&[100u8]), Err(Error::MoreBytesNeeded));
}
}