Skip to main content

quanttide_devops/contract/
source.rs

1use serde::{Deserialize, Serialize};
2use std::path::Path;
3
4// ── Sources(事实源维度)──────────────────────────────────────────────
5
6/// 事实源配置。
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub struct Source {
10    #[serde(default)]
11    pub version: VersionSource,
12}
13
14impl Default for Source {
15    fn default() -> Self {
16        Self {
17            version: VersionSource {
18                source_type: SourceType::Auto,
19                path: None,
20            },
21        }
22    }
23}
24
25/// 版本号来源配置。
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(rename_all = "snake_case")]
28pub struct VersionSource {
29    /// YAML key 为 `type`(Rust 保留字,故字段命名避开)。
30    #[serde(default, rename = "type")]
31    pub source_type: SourceType,
32    #[serde(default)]
33    pub path: Option<String>,
34}
35
36impl Default for VersionSource {
37    fn default() -> Self {
38        Self {
39            source_type: SourceType::Auto,
40            path: None,
41        }
42    }
43}
44
45/// 版本号读取来源。
46#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
47#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
48#[serde(rename_all = "snake_case")]
49pub enum SourceType {
50    Cargo,
51    Pyproject,
52    /// 不从配置文件读版本,只从 git tag 读。
53    TagOnly,
54    Pubspec,
55    #[serde(rename = "package.json")]
56    PackageJson,
57    /// 自动检测。
58    #[default]
59    Auto,
60}
61
62impl SourceType {
63    /// 根据目录下的文件自动检测版本源类型。
64    pub fn detect(dir: &Path) -> Self {
65        if dir.join("Cargo.toml").exists() {
66            Self::Cargo
67        } else if dir.join("pyproject.toml").exists() {
68            Self::Pyproject
69        } else if dir.join("pubspec.yaml").exists() {
70            Self::Pubspec
71        } else if dir.join("package.json").exists() {
72            Self::PackageJson
73        } else {
74            Self::TagOnly
75        }
76    }
77}