Skip to main content

_bver/
schema.rs

1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Deserialize, Serialize, Default)]
5#[serde(rename_all = "kebab-case")]
6pub struct Config {
7    pub current_version: Option<String>,
8    #[serde(default, skip_serializing_if = "Option::is_none")]
9    pub context_lines: Option<usize>,
10    #[serde(default)]
11    pub default_kind: FileKind,
12    #[serde(default)]
13    pub on_invalid_version: OnInvalidVersion,
14    #[serde(default)]
15    pub git: GitConfig,
16    #[serde(default, rename = "file")]
17    pub files: Vec<FileConfig>,
18}
19
20#[derive(Debug, Deserialize, Serialize)]
21#[serde(rename_all = "kebab-case")]
22pub struct GitConfig {
23    #[serde(default = "default_actions")]
24    pub actions: Vec<Action>,
25    #[serde(default)]
26    pub run_pre_commit: RunPreCommit,
27    #[serde(default = "default_tag_template")]
28    pub tag_template: String,
29    #[serde(default = "default_commit_template")]
30    pub commit_template: String,
31    #[serde(default = "default_branch_template")]
32    pub branch_template: String,
33}
34
35impl Default for GitConfig {
36    fn default() -> Self {
37        Self {
38            actions: default_actions(),
39            run_pre_commit: RunPreCommit::default(),
40            tag_template: default_tag_template(),
41            commit_template: default_commit_template(),
42            branch_template: default_branch_template(),
43        }
44    }
45}
46
47impl GitConfig {
48    pub fn has(&self, action: Action) -> bool {
49        self.actions.contains(&action)
50    }
51
52    pub fn validate(&self) -> Result<(), String> {
53        if self.has(Action::Tag) && !self.has(Action::Commit) {
54            return Err("git action 'tag' requires 'commit'".to_string());
55        }
56        if self.has(Action::Push) && !self.has(Action::Commit) {
57            return Err("git action 'push' requires 'commit'".to_string());
58        }
59        if self.has(Action::Pr) && !self.has(Action::Push) {
60            return Err("git action 'pr' requires 'push'".to_string());
61        }
62        if self.has(Action::Pr) && !self.has(Action::Branch) {
63            return Err("git action 'pr' requires 'branch'".to_string());
64        }
65        if self.has(Action::Tag) && self.has(Action::Branch) {
66            return Err("git actions 'tag' and 'branch' cannot coexist".to_string());
67        }
68        Ok(())
69    }
70}
71
72fn default_actions() -> Vec<Action> {
73    vec![Action::AddAll, Action::Commit, Action::Tag]
74}
75
76fn default_tag_template() -> String {
77    "{new-version}".to_string()
78}
79
80fn default_commit_template() -> String {
81    "Bump version from {current-version} to {new-version}".to_string()
82}
83
84fn default_branch_template() -> String {
85    "release/{new-version}".to_string()
86}
87
88#[derive(Debug, Deserialize, Serialize)]
89pub struct FileConfig {
90    pub src: PathBuf,
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub kind: Option<FileKind>,
93}
94
95#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
96#[serde(rename_all = "lowercase")]
97pub enum FileKind {
98    #[default]
99    Any,
100    Simple,
101    Python,
102    Semver,
103}
104
105#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
106#[serde(rename_all = "lowercase")]
107pub enum OnInvalidVersion {
108    #[default]
109    Error,
110    Cast,
111}
112
113#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
114#[serde(rename_all = "kebab-case")]
115pub enum RunPreCommit {
116    Enabled,
117    Disabled,
118    #[default]
119    WhenPresent,
120}
121
122#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
123#[serde(rename_all = "kebab-case")]
124pub enum Action {
125    AddAll,
126    Branch,
127    Commit,
128    Tag,
129    Push,
130    Pr,
131}