///|
/// Open a fallible prefix-listing cursor. The returned resource should be
/// closed when iteration stops before end-of-stream.
pub fn Operator::open_lister(
self : Operator,
path : StringView,
recursive? : Bool = false,
limit? : UInt64,
start_after? : StringView,
) -> Lister raise OpenDalError {
let path = path.to_owned()
let has_limit = limit is Some(_)
let limit = limit.unwrap_or(0UL)
let (has_start_after, start_after) = normalize_optional_text(start_after)
let result = native_operator_lister(
self, path, recursive, has_limit, limit, has_start_after, start_after,
)
if native_result_status(result) != 0U {
raise error_from_native_result(result, List, Some(path), None)
}
let native = native_result_take_lister(result)
if native_result_status(result) != 0U {
raise error_from_native_result(result, List, Some(path), None)
}
native_result_release(result)
{ native, path }
}
///|
/// Return the next entry, None at end-of-stream, or raise on failure.
/// End-of-stream is stable. An I/O failure is terminal.
pub fn Lister::next(self : Lister) -> Entry? raise OpenDalError {
let result = native_lister_next(self.native)
match native_result_status(result) {
0U => {
let entry = native_result_take_entry(result)
if native_result_status(result) != 0U {
self.close()
raise error_from_native_result(result, List, Some(self.path), None)
}
native_result_release(result)
let converted = try entry_from_native(entry, self.path) catch {
error => {
self.close()
raise error
}
} noraise {
value => value
}
Some(converted)
}
1U => {
native_result_release(result)
None
}
_ => {
self.close()
raise error_from_native_result(result, List, Some(self.path), None)
}
}
}
///|
/// Release listing resources early. Closing more than once is harmless.
pub fn Lister::close(self : Lister) -> Unit {
native_lister_close(self.native)
}
///|
/// Materialize a prefix listing into memory. The optional limit is a backend
/// request hint rather than a total-result bound.
pub fn Operator::list(
self : Operator,
path : StringView,
recursive? : Bool = false,
limit? : UInt64,
start_after? : StringView,
) -> Array[Entry] raise OpenDalError {
let path = path.to_owned()
let lister = self.open_lister(path, recursive~, limit?, start_after?)
let entries : Array[Entry] = []
try {
for ;; {
match lister.next() {
Some(entry) => {
if entries.length() == 2147483647 {
raise binding_error(
BufferTooLarge,
List,
"list has too many entries to materialize in a MoonBit Array",
Some(path),
None,
)
}
entries.push(entry)
}
None => break
}
}
lister.close()
entries
} catch {
error => {
lister.close()
raise error
}
} noraise {
value => value
}
}