apsis-rs/crates/ops/apsis-conflict/src/lib.rs

61 lines
2.3 KiB
Rust

//! Resource and time conflict detection.
//!
//! 资源与时间冲突检测。
//!
//! A schedule can be wrong in several ways, and this crate finds them. It
//! reports conflicts rather than refusing them, so that a plan loaded from a
//! file can be checked in full and every problem listed at once instead of
//! one per attempt.
//!
//! Five kinds of conflict are detected:
//!
//! - **Capacity**: two placements need more of a resource at the same instant
//! than the resource has.
//! - **Window**: a placement starts before its task may, or ends after it
//! must.
//! - **Requirement**: a placement's task is not known, or its duration does
//! not match the schedule.
//! - **Availability**: a placement falls outside the availability windows of
//! a resource it needs, so the resource would not actually be there.
//! - **Precedence**: a task that must follow another starts before it ends.
//!
//! The distinction between a capacity conflict and an availability conflict
//! matters in practice: the first says the plan is over committed, the second
//! says the plan asks for a resource at a time when it is switched off or out
//! of view, which is a different repair.
//!
//! ```
//! use apsis_resource::{Resource, ResourceId, ResourceSet, Window};
//! use apsis_schedule::Schedule;
//! use apsis_task::{Task, TaskId};
//! use apsis_conflict::{ConflictKind, detect};
//!
//! let mut station = Resource::new(ResourceId::new(0), 1.0);
//! station.set_windows(&[Window::new(0.0, 1_000.0)]).expect("usable");
//! let resources = ResourceSet::from_resources(vec![station]).expect("distinct");
//!
//! let task = Task::new(TaskId::new(0), 60.0)
//! .try_require(ResourceId::new(0), 1.0)
//! .expect("the resource is new");
//! let mut schedule = Schedule::new();
//! schedule.place(&task, 100.0).expect("the task fits");
//!
//! let report = detect(&schedule, &[task], &resources);
//! assert!(report.is_clear());
//! assert_eq!(report.conflicts().len(), 0);
//! let _ = ConflictKind::Capacity;
//! ```
#![forbid(unsafe_code)]
#![deny(missing_docs)]
mod conflict;
mod detect;
pub use conflict::{Conflict, ConflictKind, ConflictReport};
pub use detect::{Precedence, detect, detect_precedence, placements_of};
pub use apsis_resource::{ResourceId, ResourceSet};
pub use apsis_schedule::Schedule;
pub use apsis_task::{Task, TaskId};