pub trait Resource: Any + 'static {
fn name(&self) -> Cow<'_, str> { ... }
fn read(self: Rc<Self>, limit: usize) -> AsyncResult<BufView> { ... }
fn read_byob(
self: Rc<Self>,
buf: BufMutView
) -> AsyncResult<(usize, BufMutView)> { ... }
fn write(self: Rc<Self>, buf: BufView) -> AsyncResult<WriteOutcome> { ... }
fn write_all(self: Rc<Self>, view: BufView) -> AsyncResult<()> { ... }
fn shutdown(self: Rc<Self>) -> AsyncResult<()> { ... }
fn close(self: Rc<Self>) { ... }
fn backing_fd(self: Rc<Self>) -> Option<RawFd> { ... }
fn size_hint(&self) -> (u64, Option<u64>) { ... }
}
Expand description
Resources are Rust objects that are attached to a [deno_core::JsRuntime]. They are identified in JS by a numeric ID (the resource ID, or rid). Resources can be created in ops. Resources can also be retrieved in ops by their rid. Resources are not thread-safe - they can only be accessed from the thread that the JsRuntime lives on.
Resources are reference counted in Rust. This means that they can be cloned and passed around. When the last reference is dropped, the resource is automatically closed. As long as the resource exists in the resource table, the reference count is at least 1.
Readable
Readable resources are resources that can have data read from. Examples of this are files, sockets, or HTTP streams.
Readables can be read from from either JS or Rust. In JS one can use
Deno.core.read()
to read from a single chunk of data from a readable. In
Rust one can directly call read()
or read_byob()
. The Rust side code is
used to implement ops like op_slice
.
A distinction can be made between readables that produce chunks of data themselves (they allocate the chunks), and readables that fill up bring-your-own-buffers (BYOBs). The former is often the case for framed protocols like HTTP, while the latter is often the case for kernel backed resources like files and sockets.
All readables must implement read()
. If resources can support an optimized
path for BYOBs, they should also implement read_byob()
. For kernel backed
resources it often makes sense to implement read_byob()
first, and then
implement read()
as an operation that allocates a new chunk with
len == limit
, then calls read_byob()
, and then returns a chunk sliced to
the number of bytes read. Kernel backed resources can use the
[deno_core::impl_readable_byob] macro to implement optimized read_byob()
and read()
implementations from a single Self::read()
method.
Writable
Writable resources are resources that can have data written to. Examples of this are files, sockets, or HTTP streams.
Writables can be written to from either JS or Rust. In JS one can use
Deno.core.write()
to write to a single chunk of data to a writable. In
Rust one can directly call write()
. The latter is used to implement ops
like op_slice
.
Provided Methods§
sourcefn name(&self) -> Cow<'_, str>
fn name(&self) -> Cow<'_, str>
Returns a string representation of the resource which is made available
to JavaScript code through op_resources
. The default implementation
returns the Rust type name, but specific resource types may override this
trait method.
sourcefn read(self: Rc<Self>, limit: usize) -> AsyncResult<BufView>
fn read(self: Rc<Self>, limit: usize) -> AsyncResult<BufView>
Read a single chunk of data from the resource. This operation returns a
BufView
that represents the data that was read. If a zero length buffer
is returned, it indicates that the resource has reached EOF.
If this method is not implemented, the default implementation will error with a “not supported” error.
If a readable can provide an optimized path for BYOBs, it should also
implement read_byob()
.
sourcefn read_byob(self: Rc<Self>, buf: BufMutView) -> AsyncResult<(usize, BufMutView)>
fn read_byob(self: Rc<Self>, buf: BufMutView) -> AsyncResult<(usize, BufMutView)>
Read a single chunk of data from the resource into the provided BufMutView
.
This operation returns the number of bytes read. If zero bytes are read, it indicates that the resource has reached EOF.
If this method is not implemented explicitly, the default implementation
will call read()
and then copy the data into the provided buffer. For
readable resources that can provide an optimized path for BYOBs, it is
strongly recommended to override this method.
sourcefn write(self: Rc<Self>, buf: BufView) -> AsyncResult<WriteOutcome>
fn write(self: Rc<Self>, buf: BufView) -> AsyncResult<WriteOutcome>
Write a single chunk of data to the resource. The operation may not be
able to write the entire chunk, in which case it should return the number
of bytes written. Additionally it should return the BufView
that was
passed in.
If this method is not implemented, the default implementation will error with a “not supported” error.
sourcefn write_all(self: Rc<Self>, view: BufView) -> AsyncResult<()>
fn write_all(self: Rc<Self>, view: BufView) -> AsyncResult<()>
Write an entire chunk of data to the resource. Unlike write()
, this will
ensure the entire chunk is written. If the operation is not able to write
the entire chunk, an error is to be returned.
By default this method will call write()
repeatedly until the entire
chunk is written. Resources that can write the entire chunk in a single
operation using an optimized path should override this method.
sourcefn shutdown(self: Rc<Self>) -> AsyncResult<()>
fn shutdown(self: Rc<Self>) -> AsyncResult<()>
The shutdown method can be used to asynchronously close the resource. It is not automatically called when the resource is dropped or closed.
If this method is not implemented, the default implementation will error with a “not supported” error.
sourcefn close(self: Rc<Self>)
fn close(self: Rc<Self>)
Resources may implement the close()
trait method if they need to do
resource specific clean-ups, such as cancelling pending futures, after a
resource has been removed from the resource table.
sourcefn backing_fd(self: Rc<Self>) -> Option<RawFd>
fn backing_fd(self: Rc<Self>) -> Option<RawFd>
Resources backed by a file descriptor can let ops know to allow for low-level optimizations.