hg_git_fast_import/
config.rs

1use serde;
2use serde::{Deserialize, Serialize};
3
4use std::collections::HashMap;
5use std::path::PathBuf;
6
7#[derive(Debug, Deserialize, Serialize, PartialEq)]
8pub struct RepositoryConfig {
9    pub offset: Option<usize>,
10    pub authors: Option<HashMap<String, String>>,
11    pub branches: Option<HashMap<String, String>>,
12    #[serde(default)]
13    pub allow_unnamed_heads: bool,
14    #[serde(skip_deserializing)]
15    pub limit_high: Option<usize>,
16    pub path_prefix: Option<String>,
17    pub branch_prefix: Option<String>,
18    pub tag_prefix: Option<String>,
19    #[serde(default)]
20    pub prefix_default_branch: bool,
21    pub default_branch: Option<String>,
22}
23
24impl RepositoryConfig {
25    pub fn default_branch(&self) -> Option<&str> {
26        self.default_branch.as_deref()
27    }
28}
29
30impl Default for RepositoryConfig {
31    fn default() -> Self {
32        Self {
33            offset: None,
34            authors: None,
35            branches: None,
36            allow_unnamed_heads: true,
37            limit_high: None,
38            path_prefix: None,
39            branch_prefix: None,
40            tag_prefix: None,
41            prefix_default_branch: false,
42            default_branch: None,
43        }
44    }
45}
46
47#[derive(Debug, Deserialize, Serialize, Default, PartialEq)]
48pub struct PathRepositoryConfig {
49    pub alias: Option<String>,
50    pub path_hg: PathBuf,
51    pub path_git: PathBuf,
52    #[serde(default)]
53    pub config: RepositoryConfig,
54    pub merged_branches: Option<HashMap<String, String>>,
55}
56
57#[derive(Debug, Deserialize, Serialize, PartialEq)]
58pub struct MultiConfig {
59    pub path_git: PathBuf,
60    pub repositories: Vec<PathRepositoryConfig>,
61    default_branch: Option<String>,
62}
63
64impl MultiConfig {
65    pub fn default_branch(&self) -> Option<&str> {
66        self.default_branch.as_deref()
67    }
68}
69
70#[derive(Debug, Deserialize, Serialize)]
71#[serde(tag = "type", content = "value")]
72pub enum RepositorySavedState {
73    OffsetedRevision(usize, usize),
74}
75
76#[cfg(test)]
77mod tests {
78    use pretty_assertions::assert_eq;
79
80    #[test]
81    fn repository_saved_state_to_toml() {
82        let expected = "type = \"OffsetedRevision\"\nvalue = [100, 200]\n";
83        let result =
84            toml::to_string(&super::RepositorySavedState::OffsetedRevision(100, 200)).unwrap();
85        assert_eq!(expected, result);
86    }
87
88    #[test]
89    fn singleconfig_read_from_toml() {
90        let src = include_str!("../examples/single.toml");
91        let result: super::RepositoryConfig = toml::from_str(src).unwrap();
92        assert_eq!(
93            result,
94            super::RepositoryConfig {
95                allow_unnamed_heads: true,
96                offset: Some(1000),
97                path_prefix: Some("prefix1".into()),
98                tag_prefix: Some("prefix2-".into()),
99                branch_prefix: Some("prefix3-".into()),
100                authors: Some(
101                    vec![
102                        ("aaa 1".into(), "Bbb <bbb@company.xyz>".into()),
103                        ("aaa".into(), "Bbb <bbb@company.xyz>".into()),
104                        ("ccc".into(), "Qqq <qqq@another.dom>".into()),
105                        ("My <my_typo@wrong.xyz>".into(), "My <my@normal.xyz>".into()),
106                    ]
107                    .into_iter()
108                    .collect()
109                ),
110                branches: Some(
111                    vec![
112                        ("anotherhg".into(), "othergit".into()),
113                        ("branch in hg".into(), "branch-in-git".into()),
114                    ]
115                    .into_iter()
116                    .collect()
117                ),
118                default_branch: Some("main".into()),
119                ..Default::default()
120            }
121        )
122    }
123
124    #[test]
125    fn multiconfig_read_from_toml() {
126        let src = include_str!("../examples/multi.toml");
127        let result: super::MultiConfig = toml::from_str(src).unwrap();
128
129        assert_eq!(
130            result,
131            super::MultiConfig {
132                path_git: "000_git".into(),
133                default_branch: Some("main".into()),
134                repositories: vec![
135                    super::PathRepositoryConfig {
136                        path_hg: "001_hg".into(),
137                        path_git: "001_git".into(),
138                        config: super::RepositoryConfig {
139                            allow_unnamed_heads: true,
140                            offset: Some(1000),
141                            path_prefix: Some("prefix1".into()),
142                            tag_prefix: Some("prefix2-".into()),
143                            branch_prefix: Some("prefix3-".into()),
144                            prefix_default_branch: true,
145                            authors: Some(
146                                vec![("aaa".into(), "Bbb <bbb@company.xyz>".into()),]
147                                    .into_iter()
148                                    .collect()
149                            ),
150                            branches: Some(
151                                vec![("branch1".into(), "branch2".into()),]
152                                    .into_iter()
153                                    .collect()
154                            ),
155                            ..Default::default()
156                        },
157                        merged_branches: Some(
158                            vec![("branch_in_git".into(), "branch2".into()),]
159                                .into_iter()
160                                .collect()
161                        ),
162                        ..Default::default()
163                    },
164                    super::PathRepositoryConfig {
165                        alias: Some("another_002".into()),
166                        path_hg: "002_hg".into(),
167                        path_git: "002_git".into(),
168                        config: super::RepositoryConfig {
169                            ..Default::default()
170                        },
171                        merged_branches: Some(
172                            vec![("branch_in_git".into(), "branch_in_hg".into()),]
173                                .into_iter()
174                                .collect()
175                        ),
176                    }
177                ]
178            }
179        );
180    }
181}