1use serde::{Deserialize, Serialize};
2
3use crate::Dependency;
4
5#[derive(Debug, Serialize, Deserialize, Clone)]
6pub struct Manifest {
7 pub author: Option<String>,
8 pub license: Option<String>,
9 pub name: String,
10 #[serde(default)]
11 pub formatter: FormatterConfigManifestFormat,
12 #[serde(default)]
13 pub dependencies: BTreeMap<String, Dependency>,
14}
15
16#[derive(Debug, Serialize, Deserialize, Clone, Default)]
17pub struct FormatterConfigManifestFormat {
18 pub put_fn_params_on_new_lines: Option<bool>,
19 pub use_set_notation_for_types: Option<bool>,
20 pub join_comments: Option<bool>,
21 pub newlines_between_items: Option<usize>,
22 pub newlines_between_comment_and_item: Option<usize>,
23 pub put_variants_on_new_lines: Option<bool>,
24 pub put_list_elements_on_new_lines: Option<bool>,
25 pub put_fn_body_on_new_line: Option<bool>,
26 pub tab_size: Option<usize>,
27 pub max_line_length: Option<usize>,
28 pub put_fn_args_on_new_lines: Option<bool>,
29 pub put_trailing_semis_on_let_bindings: Option<bool>,
30 pub backup: Option<bool>,
31}
32
33impl From<FormatterConfigManifestFormat> for petr_fmt::FormatterConfig {
36 fn from(value: FormatterConfigManifestFormat) -> Self {
37 let mut builder = petr_fmt::FormatterConfigBuilder::default();
38 if let Some(conf) = value.put_fn_params_on_new_lines {
39 builder = builder.put_fn_params_on_new_lines(conf);
40 };
41 if let Some(conf) = value.use_set_notation_for_types {
42 builder = builder.use_set_notation_for_types(conf);
43 };
44 if let Some(conf) = value.join_comments {
45 builder = builder.join_comments(conf);
46 };
47 if let Some(conf) = value.newlines_between_items {
48 builder = builder.newlines_between_items(conf);
49 };
50 if let Some(conf) = value.newlines_between_comment_and_item {
51 builder = builder.newlines_between_comment_and_item(conf);
52 };
53 if let Some(conf) = value.put_variants_on_new_lines {
54 builder = builder.put_variants_on_new_lines(conf);
55 };
56 if let Some(conf) = value.put_list_elements_on_new_lines {
57 builder = builder.put_list_elements_on_new_lines(conf);
58 };
59 if let Some(conf) = value.put_fn_body_on_new_line {
60 builder = builder.put_fn_body_on_new_line(conf);
61 };
62 if let Some(conf) = value.tab_size {
63 builder = builder.tab_size(conf);
64 };
65 if let Some(conf) = value.max_line_length {
66 builder = builder.max_line_length(conf);
67 };
68 if let Some(conf) = value.put_fn_args_on_new_lines {
69 builder = builder.put_fn_args_on_new_lines(conf);
70 };
71 if let Some(conf) = value.put_trailing_semis_on_let_bindings {
72 builder = builder.put_trailing_semis_on_let_bindings(conf);
73 };
74 if let Some(conf) = value.backup {
75 builder = builder.backup(conf);
76 };
77
78 builder.build()
79 }
80}
81
82use std::{
84 collections::BTreeMap,
85 fs,
86 path::{Path, PathBuf},
87};
88
89pub fn find_manifest(path: Option<PathBuf>) -> Result<Manifest, Box<dyn std::error::Error>> {
90 fn search_dir(path: &Path) -> Option<PathBuf> {
91 let manifest_path = path.join("pete.toml");
92 if manifest_path.exists() {
93 return Some(manifest_path);
94 }
95 path.parent().and_then(search_dir)
96 }
97
98 let start_path = path.unwrap_or_else(|| std::env::current_dir().unwrap());
99 let manifest_path = search_dir(&start_path).ok_or("Manifest file not found")?;
100 let manifest_content = fs::read_to_string(manifest_path)?;
101 let manifest = toml::from_str(&manifest_content)?;
102 Ok(manifest)
103}