Skip to content

Commit

Permalink
Use u64 for R2 range requests (#564)
Browse files Browse the repository at this point in the history
* Use u64 for R2 range requests

Closes #560

* address comment

* Clarify  options
  • Loading branch information
kflansburg committed May 19, 2024
1 parent 8e24a87 commit 6bf6cf7
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 24 deletions.
6 changes: 3 additions & 3 deletions worker-sys/src/types/r2/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct R2Range {
pub offset: Option<u32>,
pub length: Option<u32>,
pub suffix: Option<u32>,
pub offset: Option<f64>,
pub length: Option<f64>,
pub suffix: Option<f64>,
}
59 changes: 38 additions & 21 deletions worker/src/r2/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,34 +93,48 @@ impl From<Conditional> for JsObject {

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Range {
OffsetWithLength { offset: u32, length: u32 },
OffsetWithOptionalLength { offset: u32, length: Option<u32> },
OptionalOffsetWithLength { offset: Option<u32>, length: u32 },
Suffix { suffix: u32 },
/// Read `length` bytes starting at `offset`.
OffsetWithLength { offset: u64, length: u64 },
/// Read from `offset` to the end of the object.
OffsetToEnd { offset: u64 },
/// Read `length` bytes starting at the beginning of the object.
Prefix { length: u64 },
/// Read `suffix` bytes from the end of the object.
Suffix { suffix: u64 },
}

const MAX_SAFE_INTEGER: u64 = js_sys::Number::MAX_SAFE_INTEGER as u64;

fn check_range_precision(value: u64) -> f64 {
assert!(
value <= MAX_SAFE_INTEGER,
"Integer precision loss when converting to JavaScript number"
);
value as f64
}

impl From<Range> for JsObject {
fn from(val: Range) -> Self {
match val {
Range::OffsetWithLength { offset, length } => js_object! {
"offset" => Some(offset),
"length" => Some(length),
"offset" => Some(check_range_precision(offset)),
"length" => Some(check_range_precision(length)),
"suffix" => JsValue::UNDEFINED,
},
Range::OffsetWithOptionalLength { offset, length } => js_object! {
"offset" => Some(offset),
"length" => length,
Range::OffsetToEnd { offset } => js_object! {
"offset" => Some(check_range_precision(offset)),
"length" => JsValue::UNDEFINED,
"suffix" => JsValue::UNDEFINED,
},
Range::OptionalOffsetWithLength { offset, length } => js_object! {
"offset" => offset,
"length" => Some(length),
Range::Prefix { length } => js_object! {
"offset" => JsValue::UNDEFINED,
"length" => Some(check_range_precision(length)),
"suffix" => JsValue::UNDEFINED,
},
Range::Suffix { suffix } => js_object! {
"offset" => JsValue::UNDEFINED,
"length" => JsValue::UNDEFINED,
"suffix" => Some(suffix),
"suffix" => Some(check_range_precision(suffix)),
},
}
}
Expand All @@ -131,16 +145,19 @@ impl TryFrom<R2RangeSys> for Range {

fn try_from(val: R2RangeSys) -> Result<Self> {
Ok(match (val.offset, val.length, val.suffix) {
(Some(offset), Some(length), None) => Self::OffsetWithLength { offset, length },
(Some(offset), None, None) => Self::OffsetWithOptionalLength {
offset,
length: None,
(Some(offset), Some(length), None) => Self::OffsetWithLength {
offset: offset.round() as u64,
length: length.round() as u64,
},
(Some(offset), None, None) => Self::OffsetToEnd {
offset: offset.round() as u64,
},
(None, Some(length), None) => Self::Prefix {
length: length.round() as u64,
},
(None, Some(length), None) => Self::OptionalOffsetWithLength {
offset: None,
length,
(None, None, Some(suffix)) => Self::Suffix {
suffix: suffix.round() as u64,
},
(None, None, Some(suffix)) => Self::Suffix { suffix },
_ => return Err(Error::JsError("invalid range".into())),
})
}
Expand Down

0 comments on commit 6bf6cf7

Please sign in to comment.