///|
/// A half-open byte range, `[start, end)`.
///
/// Half-open rather than inclusive because every slice API in MoonBit is, and a
/// library that flips the convention at its own boundary buys one off-by-one per
/// caller. `end` of `None` means "to the end of the object".
pub(all) struct Range {
start : Int64
end : Int64?
} derive(Eq, Debug)
///|
/// From `start` to the end.
pub fn Range::from(start : Int64) -> Range {
{ start, end: None, }
}
///|
/// `[start, end)`.
pub fn Range::between(start : Int64, end : Int64) -> Range {
{ start, end: Some(end), }
}
///|
/// The first `n` bytes.
pub fn Range::prefix(n : Int64) -> Range {
{ start: 0L, end: Some(n), }
}
///|
/// Where this range lands in an object of `size` bytes, as `(offset, length)`.
///
/// `None` means `RangeNotSatisfied`: the range starts before zero, or past the
/// end. An end beyond the object clamps rather than failing, which is what HTTP
/// range semantics do and what a caller asking for "the next 4KB" wants.
pub fn Range::resolve(self : Range, size : Int64) -> (Int64, Int64)? {
guard self.start >= 0L && self.start <= size else { return None }
let end = match self.end {
None => size
Some(e) => if e > size { size } else { e }
}
guard end >= self.start else { return None }
Some((self.start, end - self.start))
}
///|
pub(all) struct ReadOptions {
range : Range?
} derive(Eq, Debug)
///|
pub fn ReadOptions::default() -> ReadOptions {
{ range: None, }
}
///|
pub(all) struct WriteOptions {
content_type : String?
/// Append to what is there instead of replacing it. Creates when absent.
append : Bool
/// Fail with `AlreadyExists` rather than overwrite.
if_not_exists : Bool
} derive(Eq, Debug)
///|
pub fn WriteOptions::default() -> WriteOptions {
{ content_type: None, append: false, if_not_exists: false, }
}
///|
pub(all) struct ListOptions {
/// Every descendant, rather than the immediate children.
recursive : Bool
/// At most this many entries.
limit : Int?
/// Resume: only entries strictly after this path, in the ascending order
/// `list` always answers in.
start_after : String?
} derive(Eq, Debug)
///|
pub fn ListOptions::default() -> ListOptions {
{ recursive: false, limit: None, start_after: None, }
}
///|
pub(all) struct DeleteOptions {
/// Delete a directory and everything under it.
recursive : Bool
} derive(Eq, Debug)
///|
pub fn DeleteOptions::default() -> DeleteOptions {
{ recursive: false, }
}