From f26a90bc96ad14bccbabeade5697723b6d51533e Mon Sep 17 00:00:00 2001 From: ApsisRS contributors Date: Fri, 2 Oct 2026 01:00:22 +0800 Subject: [PATCH] docs: bilingual comments for apsis-resource Seventy-five comment blocks across the error kinds, the resource model and the window algebra. The English is unchanged and the Chinese follows under a blank doc line, as the glossary sets out. --- crates/ops/apsis-resource/src/error.rs | 24 ++++ crates/ops/apsis-resource/src/resource.rs | 128 ++++++++++++++++++++++ crates/ops/apsis-resource/src/window.rs | 75 +++++++++++++ crates/ops/apsis-schedule/src/error.rs | 26 +++++ crates/ops/apsis-task/src/error.rs | 30 +++++ 5 files changed, 283 insertions(+) diff --git a/crates/ops/apsis-resource/src/error.rs b/crates/ops/apsis-resource/src/error.rs index fd1f244..cf36e03 100644 --- a/crates/ops/apsis-resource/src/error.rs +++ b/crates/ops/apsis-resource/src/error.rs @@ -3,20 +3,34 @@ use core::fmt; /// The category of a resource error. +/// +/// 资源错误的类别。 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum ResourceErrorKind { /// The end of an interval precedes its start. + /// + /// 区间的终点早于起点。 ReversedInterval, /// A time or duration is not finite. + /// + /// 某时刻或时长非有限。 NotFinite, /// A duration is negative. + /// + /// 时长为负。 NegativeDuration, /// The capacity is not positive and finite. + /// + /// 容量非正或非有限。 InvalidCapacity, /// No resource has the requested identifier. + /// + /// 没有资源具有所请求的标识符。 NoSuchResource, /// A resource with the identifier already exists. + /// + /// 具有该标识符的资源已存在。 DuplicateResource, } @@ -35,6 +49,8 @@ impl fmt::Display for ResourceErrorKind { } /// A failure while building or querying a resource. +/// +/// 构建或查询资源时发生的失败。 #[derive(Debug, Clone, PartialEq, Eq)] pub struct ResourceError { kind: ResourceErrorKind, @@ -43,22 +59,30 @@ pub struct ResourceError { impl ResourceError { /// Creates an error with the given category. + /// + /// 用给定类别创建一个错误。 pub fn new(kind: ResourceErrorKind) -> Self { Self { kind, detail: None } } /// Attaches a description of the values that caused the failure. + /// + /// 附加对该失败所涉数值的说明。 pub fn with_detail(mut self, detail: impl Into) -> Self { self.detail = Some(detail.into()); self } /// Returns the category of this failure. + /// + /// 返回该失败的类别。 pub fn kind(&self) -> ResourceErrorKind { self.kind } /// Returns the detail text attached to this error, if any. + /// + /// 返回附加在该错误上的说明文本,若有。 pub fn detail(&self) -> Option<&str> { self.detail.as_deref() } diff --git a/crates/ops/apsis-resource/src/resource.rs b/crates/ops/apsis-resource/src/resource.rs index 9b83f9f..4613e47 100644 --- a/crates/ops/apsis-resource/src/resource.rs +++ b/crates/ops/apsis-resource/src/resource.rs @@ -8,16 +8,25 @@ use crate::window::{Interval, Window, merge_windows, subtract_window}; /// The identifier is an index chosen by the caller. It is deliberately opaque /// to this crate so that a caller can use whatever numbering its own model /// provides. +/// +/// 资源的标识符。 +/// +/// 标识符是由调用方选定的下标。它对本 crate 刻意保持不透明,以便调用方 +/// 使用其自身模型所提供的任何编号方式。 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct ResourceId(pub usize); impl ResourceId { /// Creates an identifier. + /// + /// 创建一个标识符。 pub const fn new(index: usize) -> Self { Self(index) } /// Returns the index. + /// + /// 返回该下标。 pub const fn index(self) -> usize { self.0 } @@ -35,17 +44,31 @@ impl core::fmt::Display for ResourceId { /// that occupies more than the capacity of a resource cannot be scheduled on /// it at all; two tasks conflict when their demands together exceed the /// capacity at some instant. +/// +/// 带有可用窗口与容量的资源。 +/// +/// 容量是由调用方选定单位的正数。占用量超过某资源容量的任务根本无法在其上 +/// 调度;当两个任务的需求之和在某瞬超出容量时,二者冲突。 #[derive(Debug, Clone, PartialEq)] pub struct Resource { /// The identifier of this resource. + /// + /// 该资源的标识符。 pub id: ResourceId, /// The capacity, in a unit the caller chooses. /// /// A capacity of one with unit demands gives an exclusive resource, where /// no two tasks overlap. A larger capacity, or fractional demands, gives /// a shared resource. + /// + /// 容量,单位由调用方选择。 + /// + /// 容量为一且需求为单位量时得到独占资源,任意两个任务都不重叠。更大的 + /// 容量或分数需求则得到共享资源。 capacity: f64, /// The availability windows, kept merged and in time order. + /// + /// 可用窗口,保持合并且按时间有序。 windows: Vec, } @@ -56,6 +79,11 @@ impl Resource { /// windows before using it. That is the safe default: a resource whose /// availability was forgotten is unavailable rather than always /// available. + /// + /// 创建无可用性、容量给定的资源。 + /// + /// 没有窗口的资源永不可用,故调用方须先添加窗口再使用。这是安全的 + /// 默认值:忘记设置可用性的资源是不可用,而非始终可用。 pub const fn new(id: ResourceId, capacity: f64) -> Self { Self { id, @@ -65,6 +93,8 @@ impl Resource { } /// Returns the capacity. + /// + /// 返回该容量。 pub const fn capacity(&self) -> f64 { self.capacity } @@ -72,6 +102,10 @@ impl Resource { /// Sets the capacity. /// /// Returns an error when the capacity is not positive and finite. + /// + /// 设置容量。 + /// + /// 当容量非正或非有限时返回错误。 pub fn set_capacity(&mut self, capacity: f64) -> Result<(), ResourceError> { if !capacity.is_finite() || capacity <= 0.0 { return Err(ResourceError::new(ResourceErrorKind::InvalidCapacity) @@ -82,21 +116,29 @@ impl Resource { } /// Returns `true` when the capacity is usable. + /// + /// 当该容量可用时返回 `true`。 pub fn has_valid_capacity(&self) -> bool { self.capacity.is_finite() && self.capacity > 0.0 } /// Returns the availability windows, merged and in time order. + /// + /// 返回可用窗口,已合并且按时间有序。 pub fn windows(&self) -> &[Window] { &self.windows } /// Returns the number of availability windows. + /// + /// 返回可用窗口的数量。 pub fn window_count(&self) -> usize { self.windows.len() } /// Returns `true` when the resource has no availability at all. + /// + /// 当该资源完全没有可用性时返回 `true`。 pub fn is_empty(&self) -> bool { self.windows.is_empty() } @@ -107,6 +149,12 @@ impl Resource { /// the caller supplies them in. /// /// Returns an error when a window is not usable. + /// + /// 用一组窗口替换可用性。 + /// + /// 窗口会被合并,故无论调用方以何种顺序给出,存储形式都是规范的。 + /// + /// 当某个窗口不可用时返回错误。 pub fn set_windows(&mut self, windows: &[Window]) -> Result<(), ResourceError> { self.windows = merge_windows(windows)?; Ok(()) @@ -117,6 +165,12 @@ impl Resource { /// The window is merged into the existing set. /// /// Returns an error when the window is not usable. + /// + /// 添加一个可用窗口。 + /// + /// 该窗口被合并进已有集合。 + /// + /// 当该窗口不可用时返回错误。 pub fn add_window(&mut self, window: Window) -> Result<(), ResourceError> { window.validate()?; let mut all = self.windows.clone(); @@ -131,6 +185,12 @@ impl Resource { /// stored window in two. /// /// Returns an error when the window is not usable. + /// + /// 移除一个可用窗口。 + /// + /// 该窗口从已有集合中被减去,可能把某个已存窗口一分为二。 + /// + /// 当该窗口不可用时返回错误。 pub fn remove_window(&mut self, removed: Window) -> Result<(), ResourceError> { self.windows = subtract_window(&self.windows, removed)?; Ok(()) @@ -141,6 +201,11 @@ impl Resource { /// An instantaneous query is a query of zero duration, which is satisfied /// when the instant is inside a window. At the end of a window the /// resource is not available, because the window is half-open. + /// + /// 当该资源在某瞬可用时返回 `true`。 + /// + /// 瞬时查询即零时长查询,当该瞬落在某个窗口内即得到满足。在窗口 + /// 终点处该资源不可用,因为窗口是半开的。 pub fn is_available_at(&self, time: f64) -> bool { self.windows .iter() @@ -152,6 +217,10 @@ impl Resource { /// A resource can satisfy a request of zero duration whenever it is /// available at the requested instant, so a zero duration is checked as /// an instant. + /// + /// 当该资源在整段区间上可用时返回 `true`。 + /// + /// 只要资源在所请求瞬时可用,即可满足零时长请求,故零时长按瞬时检查。 pub fn is_available_over(&self, start: f64, duration: f64) -> bool { if !start.is_finite() || !duration.is_finite() || duration < 0.0 { return false; @@ -170,6 +239,11 @@ impl Resource { /// The result is the intersection of the stored windows with the query, /// which is what a scheduler needs to know when it asks what part of its /// planning horizon a resource is usable for. + /// + /// 返回落在某区间内的可用性。 + /// + /// 结果是已存窗口与该查询的交集,这正是调度器在询问资源的规划时域中 + /// 哪一段可用时所需的信息。 pub fn availability_within(&self, query: Interval) -> Vec { self.windows .iter() @@ -181,6 +255,10 @@ impl Resource { /// Returns the total availability, in seconds. /// /// The windows are disjoint, so the durations add. + /// + /// 返回总可用时长,单位为秒。 + /// + /// 各窗口互不相交,故时长可直接相加。 pub fn total_availability(&self) -> f64 { self.windows.iter().map(Window::duration).sum() } @@ -190,6 +268,11 @@ impl Resource { /// This is the earliest time at which the resource can satisfy a request /// of the given duration, which is what a greedy scheduler asks. Returns /// `None` when no window is long enough. + /// + /// 返回第一个能容纳某请求的窗口。 + /// + /// 这是该资源能满足给定时长请求的最早时刻,即贪心调度器所询问的量。 + /// 没有足够长的窗口时返回 `None`。 pub fn earliest_fit(&self, duration: f64) -> Option { if !duration.is_finite() || duration < 0.0 { return None; @@ -204,6 +287,10 @@ impl Resource { /// than a given time. /// /// Returns `None` when no window is both late enough and long enough. + /// + /// 返回第一个能容纳请求的窗口,且该请求的起点不早于给定时刻。 + /// + /// 没有既够晚又够长的窗口时返回 `None`。 pub fn earliest_fit_after(&self, not_before: f64, duration: f64) -> Option { if !not_before.is_finite() || !duration.is_finite() || duration < 0.0 { return None; @@ -219,6 +306,10 @@ impl Resource { /// /// Returns `None` when the resource is not available at the given /// instant, and infinity when the window that contains it is unbounded. + /// + /// 返回该资源不再可用的时刻。 + /// + /// 该资源在所给瞬时不可用时返回 `None`;包含该瞬的窗口无界时返回无穷。 pub fn busy_until(&self, time: f64) -> Option { self.windows .iter() @@ -232,6 +323,11 @@ impl Resource { /// The set keeps the resources in the order they were added and provides the /// lookups a scheduler needs: by identifier, and by the resource that has a /// window covering an instant. +/// +/// 以标识符为索引的资源集合。 +/// +/// 该集合按添加顺序保存资源,并提供调度器所需的查找:按标识符,以及按 +/// 某个瞬时上有窗口覆盖的资源。 #[derive(Debug, Clone, PartialEq, Default)] pub struct ResourceSet { resources: Vec, @@ -239,6 +335,8 @@ pub struct ResourceSet { impl ResourceSet { /// Creates an empty set. + /// + /// 创建一个空集合。 pub const fn new() -> Self { Self { resources: Vec::new(), @@ -249,6 +347,10 @@ impl ResourceSet { /// /// Returns an error when two resources share an identifier, because a /// lookup would then be ambiguous. + /// + /// 由一组资源创建集合。 + /// + /// 两个资源标识符相同时返回错误,因为查找将有歧义。 pub fn from_resources(resources: Vec) -> Result { let mut set = Self::new(); for resource in resources { @@ -260,6 +362,10 @@ impl ResourceSet { /// Inserts a resource. /// /// Returns an error when the identifier is already present. + /// + /// 插入一个资源。 + /// + /// 该标识符已存在时返回错误。 pub fn insert(&mut self, resource: Resource) -> Result<(), ResourceError> { if self.get(resource.id).is_some() { return Err(ResourceError::new(ResourceErrorKind::DuplicateResource) @@ -270,11 +376,15 @@ impl ResourceSet { } /// Returns the resource with the given identifier. + /// + /// 返回具有所给标识符的资源。 pub fn get(&self, id: ResourceId) -> Option<&Resource> { self.resources.iter().find(|resource| resource.id == id) } /// Returns the resource with the given identifier for modification. + /// + /// 返回具有所给标识符的资源以供修改。 pub fn get_mut(&mut self, id: ResourceId) -> Option<&mut Resource> { self.resources.iter_mut().find(|resource| resource.id == id) } @@ -282,6 +392,10 @@ impl ResourceSet { /// Removes a resource. /// /// Returns an error when no resource has the identifier. + /// + /// 移除一个资源。 + /// + /// 没有资源具有该标识符时返回错误。 pub fn remove(&mut self, id: ResourceId) -> Result { let index = self .resources @@ -294,16 +408,22 @@ impl ResourceSet { } /// Returns the resources in the order they were added. + /// + /// 返回按添加顺序排列的资源。 pub fn resources(&self) -> &[Resource] { &self.resources } /// Returns the number of resources. + /// + /// 返回资源数量。 pub fn len(&self) -> usize { self.resources.len() } /// Returns `true` when there are no resources. + /// + /// 当集合中没有资源时返回 `true`。 pub fn is_empty(&self) -> bool { self.resources.is_empty() } @@ -311,6 +431,10 @@ impl ResourceSet { /// Returns the identifiers of the resources available at an instant. /// /// The result is in the order the resources were added. + /// + /// 返回在某瞬可用的资源标识符。 + /// + /// 结果按资源添加顺序排列。 pub fn available_at(&self, time: f64) -> Vec { self.resources .iter() @@ -321,6 +445,8 @@ impl ResourceSet { /// Returns the identifiers of the resources available for a whole /// interval. + /// + /// 返回在整段区间上可用的资源标识符。 pub fn available_over(&self, start: f64, duration: f64) -> Vec { self.resources .iter() @@ -330,6 +456,8 @@ impl ResourceSet { } /// Returns the total availability of every resource, in seconds. + /// + /// 返回每个资源的总可用时长,单位为秒。 pub fn total_availability(&self) -> f64 { self.resources .iter() diff --git a/crates/ops/apsis-resource/src/window.rs b/crates/ops/apsis-resource/src/window.rs index 78bda9f..98e438f 100644 --- a/crates/ops/apsis-resource/src/window.rs +++ b/crates/ops/apsis-resource/src/window.rs @@ -10,16 +10,28 @@ use core::fmt; /// instant at the boundary, which belongs to the second. Two intervals are /// therefore disjoint when the end of the first is at or before the start of /// the second. +/// +/// 半开时间区间 `[start, end)`。 +/// +/// 采用半开约定正是为了使区间既不重叠也无空隙地铺满:一个在某处结束、 +/// 另一处从此开始的区间只在边界那一瞬相交,而该瞬归后者。故当第一个区 +/// 间的终点不晚于第二个区间的起点时,二者不相交。 #[derive(Debug, Clone, Copy, PartialEq)] pub struct Interval { /// The start of the interval, in seconds. + /// + /// 区间起点,单位为秒。 pub start: f64, /// The end of the interval, in seconds. + /// + /// 区间终点,单位为秒。 pub end: f64, } impl Interval { /// Creates an interval. + /// + /// 创建一个区间。 pub const fn new(start: f64, end: f64) -> Self { Self { start, end } } @@ -27,16 +39,24 @@ impl Interval { /// Returns the duration of the interval, in seconds. /// /// The value is zero for an empty interval and positive otherwise. + /// + /// 返回该区间的时长,单位为秒。 + /// + /// 对空区间该值为零,其余情形为正。 pub fn duration(&self) -> f64 { (self.end - self.start).max(0.0) } /// Returns `true` when the interval contains no time. + /// + /// 当该区间不含任何时刻时返回 `true`。 pub fn is_empty(&self) -> bool { self.end <= self.start } /// Returns `true` when the interval is finite and ordered. + /// + /// 当该区间有限且次序正确时返回 `true`。 pub fn is_valid(&self) -> bool { self.start.is_finite() && self.end.is_finite() && self.end >= self.start } @@ -45,6 +65,10 @@ impl Interval { /// /// The start is included and the end is excluded, so a boundary instant /// belongs to the interval that begins there. + /// + /// 当某时刻落在该区间内时返回 `true`。 + /// + /// 含起点不含终点,故边界时刻归由此处开始的区间。 pub fn contains(&self, time: f64) -> bool { time >= self.start && time < self.end } @@ -53,6 +77,10 @@ impl Interval { /// /// An empty interval is contained by any interval that contains its /// instant, so a zero length query inside the range is satisfied. + /// + /// 当该区间完全包含另一区间时返回 `true`。 + /// + /// 空区间被任何包含其瞬时的区间所包含,故范围内的零长度查询得到满足。 pub fn contains_interval(&self, other: &Self) -> bool { if other.is_empty() { return other.start >= self.start && other.start <= self.end; @@ -64,12 +92,18 @@ impl Interval { /// /// Two intervals that meet at a point do not overlap, because the point /// belongs to only one of them under the half-open convention. + /// + /// 当两个区间共享任一时刻时返回 `true`。 + /// + /// 在一点相接的两个区间不重叠,因为在半开约定下该点只属于其中之一。 pub fn overlaps(&self, other: &Self) -> bool { self.start < other.end && other.start < self.end } /// Returns the intersection of two intervals, or `None` when they do not /// overlap. + /// + /// 返回两个区间的交集;二者不重叠时返回 `None`。 pub fn intersection(&self, other: &Self) -> Option { if !self.overlaps(other) { return None; @@ -81,12 +115,16 @@ impl Interval { } /// Returns the shortest interval containing both. + /// + /// 返回包含二者的最短区间。 pub fn hull(&self, other: &Self) -> Self { Self::new(self.start.min(other.start), self.end.max(other.end)) } /// Returns `true` when the two intervals touch or overlap, so that they /// can be merged without leaving a gap. + /// + /// 当两个区间相接或重叠时返回 `true`,此时合并它们不会留下空隙。 pub fn is_adjacent_to(&self, other: &Self) -> bool { self.start <= other.end && other.start <= self.end } @@ -102,14 +140,23 @@ impl fmt::Display for Interval { /// /// This is an [`Interval`] under a name that reads better where the caller is /// describing when a resource can be used rather than doing interval algebra. +/// +/// 资源的可用窗口。 +/// +/// 它就是一个 [`Interval`],只是当调用方描述资源何时可用、而非进行区间运算 +/// 时,这个名字读起来更贴切。 #[derive(Debug, Clone, Copy, PartialEq)] pub struct Window { /// The interval during which the resource is available. + /// + /// 资源可用的时间区间。 pub interval: Interval, } impl Window { /// Creates a window from a start and an end time. + /// + /// 由起始时刻与结束时刻创建窗口。 pub const fn new(start: f64, end: f64) -> Self { Self { interval: Interval::new(start, end), @@ -117,31 +164,43 @@ impl Window { } /// Creates a window from an interval. + /// + /// 由区间创建窗口。 pub const fn from_interval(interval: Interval) -> Self { Self { interval } } /// Returns the start of the window, in seconds. + /// + /// 返回窗口起点,单位为秒。 pub const fn start(&self) -> f64 { self.interval.start } /// Returns the end of the window, in seconds. + /// + /// 返回窗口终点,单位为秒。 pub const fn end(&self) -> f64 { self.interval.end } /// Returns the duration of the window, in seconds. + /// + /// 返回窗口时长,单位为秒。 pub fn duration(&self) -> f64 { self.interval.duration() } /// Returns `true` when the window is usable. + /// + /// 当该窗口可用时返回 `true`。 pub fn is_valid(&self) -> bool { self.interval.is_valid() } /// Validates the window, returning the reason when it is not usable. + /// + /// 校验该窗口;不可用时返回原因。 pub fn validate(&self) -> Result<(), ResourceError> { if !self.interval.start.is_finite() || !self.interval.end.is_finite() { return Err(ResourceError::new(ResourceErrorKind::NotFinite) @@ -168,6 +227,13 @@ impl fmt::Display for Window { /// disjoint, and non-empty, so that two sets can be compared directly. /// /// Returns an error when a window is not usable. +/// +/// 把一组窗口合并为按时间排序的互不相交窗口。 +/// +/// 重叠或相接的窗口被合并,空窗口被丢弃。结果是一组可用窗口的规范形式: +/// 有序、互不相交且无空项,故两组可直接比较。 +/// +/// 当某个窗口不可用时返回错误。 pub fn merge_windows(windows: &[Window]) -> Result, ResourceError> { for window in windows { window.validate()?; @@ -182,6 +248,7 @@ pub fn merge_windows(windows: &[Window]) -> Result, ResourceError> { } // Sorting on the start and then the end gives a deterministic order for // intervals with equal starts. + // 先按起点再按终点排序,使起点相同的区间具有确定次序。 intervals.sort_by(|first, second| { first .start @@ -214,6 +281,13 @@ pub fn merge_windows(windows: &[Window]) -> Result, ResourceError> { /// that contains it is split in two. /// /// Returns an error when any input window is not usable. +/// +/// 从一组窗口中逐个减去某个窗口。 +/// +/// 结果是同一组可用性去掉该窗口之后的情形。完全落在被减窗口内部的窗口 +/// 消失,包含它的窗口被一分为二。 +/// +/// 当任一输入窗口不可用时返回错误。 pub fn subtract_window(windows: &[Window], removed: Window) -> Result, ResourceError> { removed.validate()?; let merged = merge_windows(windows)?; @@ -227,6 +301,7 @@ pub fn subtract_window(windows: &[Window], removed: Window) -> Result result.push(window), Some(overlap) => { // The part before the removed window, and the part after it. + // 被减窗口之前的一段,以及之后的一段。 if overlap.start > window.interval.start { result.push(Window::new(window.interval.start, overlap.start)); } diff --git a/crates/ops/apsis-schedule/src/error.rs b/crates/ops/apsis-schedule/src/error.rs index 4838a47..c5090e3 100644 --- a/crates/ops/apsis-schedule/src/error.rs +++ b/crates/ops/apsis-schedule/src/error.rs @@ -3,22 +3,38 @@ use core::fmt; /// The category of a schedule error. + /// + /// 计划错误的类别。 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum ScheduleErrorKind { /// The start time is not finite. + /// + /// 起始时刻非有限。 InvalidStart, /// The task is already placed. + /// + /// 该任务已被放置。 AlreadyPlaced, /// The task is not placed. + /// + /// 该任务未被放置。 NotPlaced, /// The placement starts before the task's window opens. + /// + /// 放置早于该任务窗口的开启时刻。 BeforeWindow, /// The placement ends after the task's window closes. + /// + /// 放置晚于该任务窗口的关闭时刻。 AfterWindow, /// The placement does not use the resources the task requires. + /// + /// 放置未使用该任务所要求的资源。 RequirementMismatch, /// A resource is used beyond its capacity. + /// + /// 某资源的使用超出其容量。 CapacityExceeded, } @@ -38,6 +54,8 @@ impl fmt::Display for ScheduleErrorKind { } /// A failure while building or evaluating a schedule. + /// + /// 构建或评估计划时发生的失败。 #[derive(Debug, Clone, PartialEq, Eq)] pub struct ScheduleError { kind: ScheduleErrorKind, @@ -46,22 +64,30 @@ pub struct ScheduleError { impl ScheduleError { /// Creates an error with the given category. + /// + /// 用给定类别创建一个错误。 pub fn new(kind: ScheduleErrorKind) -> Self { Self { kind, detail: None } } /// Attaches a description of the values that caused the failure. + /// + /// 附加对该失败所涉数值的说明。 pub fn with_detail(mut self, detail: impl Into) -> Self { self.detail = Some(detail.into()); self } /// Returns the category of this failure. + /// + /// 返回该失败的类别。 pub fn kind(&self) -> ScheduleErrorKind { self.kind } /// Returns the detail text attached to this error, if any. + /// + /// 返回附加在该错误上的说明文本,若有。 pub fn detail(&self) -> Option<&str> { self.detail.as_deref() } diff --git a/crates/ops/apsis-task/src/error.rs b/crates/ops/apsis-task/src/error.rs index d8be130..d8117aa 100644 --- a/crates/ops/apsis-task/src/error.rs +++ b/crates/ops/apsis-task/src/error.rs @@ -3,26 +3,46 @@ use core::fmt; /// The category of a task error. + /// + /// 任务错误的类别。 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum TaskErrorKind { /// The duration is not finite, or is negative. + /// + /// 时长非有限或为负。 InvalidDuration, /// A time window is not finite or ends before it starts. + /// + /// 时间窗口非有限或终点早于起点。 InvalidWindow, /// The window is shorter than the task duration. + /// + /// 窗口短于任务时长。 WindowTooShort, /// A resource demand is not positive and finite. + /// + /// 资源需求非正或非有限。 InvalidDemand, /// The same resource is required more than once. + /// + /// 同一资源被重复要求。 DuplicateRequirement, /// A priority or value is not finite. + /// + /// 优先级或某个数值非有限。 InvalidWeight, /// No task has the requested identifier. + /// + /// 没有任务具有所请求的标识符。 NoSuchTask, /// A task with the identifier already exists. + /// + /// 具有该标识符的任务已存在。 DuplicateTask, /// A precedence constraint would close a cycle. + /// + /// 某优先约束会闭成环。 PrecedenceCycle, } @@ -44,6 +64,8 @@ impl fmt::Display for TaskErrorKind { } /// A failure while building or querying a task. + /// + /// 构建或查询任务时发生的失败。 #[derive(Debug, Clone, PartialEq, Eq)] pub struct TaskError { kind: TaskErrorKind, @@ -52,22 +74,30 @@ pub struct TaskError { impl TaskError { /// Creates an error with the given category. + /// + /// 用给定类别创建一个错误。 pub fn new(kind: TaskErrorKind) -> Self { Self { kind, detail: None } } /// Attaches a description of the values that caused the failure. + /// + /// 附加对该失败所涉数值的说明。 pub fn with_detail(mut self, detail: impl Into) -> Self { self.detail = Some(detail.into()); self } /// Returns the category of this failure. + /// + /// 返回该失败的类别。 pub fn kind(&self) -> TaskErrorKind { self.kind } /// Returns the detail text attached to this error, if any. + /// + /// 返回附加在该错误上的说明文本,若有。 pub fn detail(&self) -> Option<&str> { self.detail.as_deref() }