Skip to main content

kcode_rust_libs/
model.rs

1use std::fmt;
2
3use crate::RustLibPath;
4
5/// A complete text file in a managed Rust library.
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct RustLibFile {
8    pub path: RustLibPath,
9    pub contents: String,
10}
11
12impl RustLibFile {
13    pub fn new(path: RustLibPath, contents: impl Into<String>) -> Self {
14        Self {
15            path,
16            contents: contents.into(),
17        }
18    }
19}
20
21/// The agent-facing metadata stored in a managed Rust library.
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub struct RustLibDocs {
24    /// The canonical `major.minor.patch` version without a trailing newline.
25    pub version: String,
26    /// The complete text of `Documentation.md`.
27    pub documentation: String,
28}
29
30/// A stage in the standardized Rust validation pipeline.
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
32pub enum CheckStage {
33    Fetch,
34    Format,
35    Build,
36    Clippy,
37    Test,
38    DocTest,
39}
40
41impl CheckStage {
42    pub fn as_str(self) -> &'static str {
43        match self {
44            Self::Fetch => "fetch",
45            Self::Format => "format",
46            Self::Build => "build",
47            Self::Clippy => "clippy",
48            Self::Test => "test",
49            Self::DocTest => "doc-test",
50        }
51    }
52}
53
54impl fmt::Display for CheckStage {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        f.write_str(self.as_str())
57    }
58}
59
60/// Captured output from one validation stage.
61#[derive(Clone, Debug, Eq, PartialEq)]
62pub struct CheckStageResult {
63    pub stage: CheckStage,
64    pub success: bool,
65    pub exit_code: Option<i32>,
66    pub stdout: String,
67    pub stderr: String,
68}
69
70/// The outcome of a complete (or fail-fast) Rust library validation run.
71#[derive(Clone, Debug, Eq, PartialEq)]
72pub struct CheckResult {
73    pub stages: Vec<CheckStageResult>,
74}
75
76impl CheckResult {
77    /// True only when every pipeline stage ran and passed.
78    pub fn passed(&self) -> bool {
79        self.stages.len() == 6 && self.stages.iter().all(|stage| stage.success)
80    }
81
82    /// Return the first unsuccessful stage, if one ran.
83    pub fn failure(&self) -> Option<&CheckStageResult> {
84        self.stages.iter().find(|stage| !stage.success)
85    }
86}