pi_async_fs 0.1.2

Runtime-agnostic asynchronous filesystem contracts for local and remote storage
// 增长型读取承载体的尾部追加语义标记。
//
// [`bytes::BufMut`] 能表达未初始化写入窗口与初始化提交,但它也允许固定切片
// 游标和其它不代表“保留旧内容并增长逻辑尾部”的类型。本模块用一个没有新
// 方法的项目 trait,把 `AsRef<[u8]>` 与 `BufMut` 之间额外的增长关系写成
// 明确公共合同,并通过显式 impl 排除语义不兼容的 blanket 集合。

use bytes::{BufMut, BytesMut};

// 可以由文件增长型读取在当前逻辑尾部追加已初始化字节的承载体。
//
// # 使用位置
//
// 本 trait 只用于 `FileIo` 的增长型读取。固定读取继续使用
// `AsMut<[u8]>` 和 [`crate::ReadTargetRegion`];文件写入源使用
// [`crate::DetachableWriteBuffer`];MMAP、向量化 I/O、目录和监控不使用本
// trait。
//
// # 初始化视图与追加位置
//
// 在一次增长读取开始时,`AsRef<[u8]>` 返回完整、连续、已经初始化的逻辑
// 内容 `[0, L)`。`BufMut::chunk_mut()` 的下一写入位置必须紧接逻辑尾部
// `L`,不能指向已有内容、一个与 `AsRef` 无关的游标或离散逻辑位置。
//
// 实现把后端确认写完的 `n` 字节写入 `chunk_mut()` 返回的未初始化窗口后,
// 才能调用 `BufMut::advance_mut(n)`。提交后必须同时满足:
//
// - 原前缀 `[0, L)` 长度和内容保持不变;
// - 新的完整初始化视图严格为 `[0, L + n)`;
// - 新后缀逐字节等于刚刚初始化的连续前缀;
// - 下一次 `chunk_mut()` 从新的逻辑尾部继续。
//
// `chunk_mut()` 可以只返回比剩余增长许可更短的一段连续空间,adapter 必须
// 循环处理,不能把 `remaining_mut()` 当作当前物理连续容量。只有实际完成
// 初始化的前缀可以传给 unsafe `advance_mut`。
//
// # 上限、分配与错误
//
// [`crate::ReadGrowthLimit`] 限制本次调用新增的公开有效字节数。具体类型或
// 分配器可以取得更多物理容量,但 adapter 不得读取或提交超过上限的字节。
// `Vec` 和 `BytesMut` 的 `chunk_mut()` 可能自动调用不可失败形式的 `reserve`;
// 项目可以类型化报告容量算术和逻辑上限错误,但全局分配器 OOM 仍可能按
// Rust/`bytes` 合同终止进程,不能宣称所有内存失败均可恢复。
//
// # 异步与取消边界
//
// completion 后端不得长期持有由 `chunk_mut()` 借出的地址。它应先把数据
// 读入独立 owned 中转载体,后端确认停止访问后,再同步复制和提交到本类型。
// 这样 Future 被丢弃时,已经返回调用方的 `&mut B` 不会继续被后台内核访问。
// 轮询式后端也只能在一次 poll 的合法借用范围内访问目标。
//
// # 实现开放性
//
// 本 trait 是安全、公开且未封闭的语义标记。第三方类型只有在其 `AsRef`
// 完整初始化视图与 `BufMut` 尾部提交满足上述关系时才可实现。它不增加
// `Clone`、`Copy`、`Send`、`Sync` 或 `'static`;跨线程方法会在自己的
// `where` 子句中要求 `B: Send + 'a`。
//
// 禁止为所有 `AsRef<[u8]> + BufMut` 类型提供 blanket impl,因为
// `&mut [u8]` 等合法 `BufMut` 只表示固定窗口游标,并不满足增长语义。
/// 可由增长型读取在当前逻辑尾部追加已初始化字节的缓冲区。
///
/// 读取开始时,`AsRef<[u8]>` 必须返回完整、连续、已初始化的逻辑内容
/// `[0, L)`;`BufMut::chunk_mut()` 必须从逻辑尾部 `L` 开始提供下一段空间。
/// 提交 `n` 个新字节后,原前缀必须保持不变,完整初始化视图必须变为
/// `[0, L + n)`,且下一次写入继续从新尾部开始。
///
/// 本 trait 只用于增长型读取。第三方类型仅在完整视图与尾部提交满足上述
/// 关系时才能实现;固定窗口游标不满足该合同。具体 I/O 方法另行约束线程
/// 和生命周期。
pub trait GrowableReadBuffer: AsRef<[u8]> + BufMut {}

// `Vec<u8>` 的 `AsRef` 视图是当前 `len`,`BufMut` 从 `len` 之后提交新字节。
impl GrowableReadBuffer for Vec<u8> {}

// `BytesMut` 的 `AsRef` 视图是当前 `len`,`BufMut` 从 `len` 之后提交新字节。
impl GrowableReadBuffer for BytesMut {}