Repository: awslabs/llrt
File: modules/llrt_buffer/src/buffer.rs (Rust)

Code before:
    }

    if let Some(obj) = value.as_object() {
        if let Some(ob) = ObjectBytes::from_array_buffer(obj)? {
            return Ok(ob.as_bytes().len());
        }
    }

    Err(Exception::throw_message(
        &ctx,
        "value must be typed DataView, Buffer, ArrayBuffer, Uint8Array or string",
    ))
}

fn is_buffer<'js>(ctx: Ctx<'js>, value: Value<'js>) -> Result<bool> {
    let class: Function = ctx.globals().get(stringify!(Buffer))?;
    if let Some(object) = value.as_object() {
        return Ok(object.is_instance_of(class));
    }

    Ok(false)
}

fn is_encoding(value: Value) -> Result<bool> {
    if let Some(js_string) = value.as_string() {
        if let Ok(std_string) = js_string.to_string() {
            return Ok(Encoder::from_str(std_string.as_str()).is_ok());
        }
    }

    Ok(false)
}

fn to_string(this: This<Object<'_>>, ctx: Ctx, encoding: Opt<String>) -> Result<String> {
    let typed_array = TypedArray::<u8>::from_object(this.0)?;
    let bytes: &[u8] = typed_array.as_ref();

    let encoder = Encoder::from_optional_str(encoding.as_deref()).or_throw(&ctx)?;
    encoder.encode_to_string(bytes, true).or_throw(&ctx)
}

fn subarray<'js>(
    this: This<Object<'js>>,
    ctx: Ctx<'js>,
    start: Opt<isize>,
    end: Opt<isize>,
) -> Result<Value<'js>> {
    let typed_array = TypedArray::<u8>::from_object(this.0)?;
    let array_buffer = typed_array.arraybuffer()?;
    let ab_length = array_buffer.len() as isize;
    let offset = start.map_or(0, |start| {

Review comment (bug):
We should fail here if we can't convert the JsString to rust string
```rust
let string = js_string.to_string()?;
```

Code after:
    }

    if let Some(obj) = value.as_object() {
        if let Some(ob) = ObjectBytes::from_array_buffer(obj)? {
            return Ok(ob.as_bytes().len());
        }
    }

    Err(Exception::throw_message(
        &ctx,
        "value must be typed DataView, Buffer, ArrayBuffer, Uint8Array or string",
    ))
}

fn is_buffer<'js>(ctx: Ctx<'js>, value: Value<'js>) -> Result<bool> {
    if let Some(object) = value.as_object() {
        let constructor = BufferPrimordials::get(&ctx)?;
        return Ok(object.is_instance_of(&constructor.constructor));
    }

    Ok(false)
}

fn is_encoding(value: Value) -> Result<bool> {
    if let Some(js_string) = value.as_string() {
        let std_string = js_string.to_string()?;
        return Ok(Encoder::from_str(std_string.as_str()).is_ok());
    }

    Ok(false)
}

fn to_string(this: This<Object<'_>>, ctx: Ctx, encoding: Opt<String>) -> Result<String> {
    let typed_array = TypedArray::<u8>::from_object(this.0)?;
    let bytes: &[u8] = typed_array.as_ref();

    let encoder = Encoder::from_optional_str(encoding.as_deref()).or_throw(&ctx)?;
    encoder.encode_to_string(bytes, true).or_throw(&ctx)
}

fn subarray<'js>(
    this: This<Object<'js>>,
    ctx: Ctx<'js>,
    start: Opt<isize>,
    end: Opt<isize>,
) -> Result<Value<'js>> {
    let typed_array = TypedArray::<u8>::from_object(this.0)?;
    let array_buffer = typed_array.arraybuffer()?;
    let ab_length = array_buffer.len() as isize;
    let offset = start.map_or(0, |start| {
        if start < 0 {