Skip to content

Commit 2f18854

Browse files
committed
fix!: Move functionality behind features
1 parent 2cf190f commit 2f18854

File tree

5 files changed

+145
-124
lines changed

5 files changed

+145
-124
lines changed

Cargo.toml

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,32 @@ pre-release-replacements = [
2727
{file="CHANGELOG.md", search="<!-- next-url -->", replace="<!-- next-url -->\n[Unreleased]: https://github.com/gitext-rs/git-fixture/compare/{{tag_name}}...HEAD", exactly=1},
2828
]
2929

30+
[features]
31+
cli = ["dep:clap", "dep:proc-exit", "dep:humantime"]
32+
serde = ["dep:serde", "dep:humantime", "dep:humantime-serde"]
33+
schema = ["dep:schemars", "json", "serde"]
34+
yaml = ["dep:serde_yaml", "serde"]
35+
json = ["dep:serde_json", "serde"]
36+
toml = ["dep:toml", "serde"]
37+
38+
[[bin]]
39+
name = "git-fixture"
40+
required-features = ["cli", "yaml", "json", "toml", "schema"]
41+
3042
[dependencies]
31-
serde = { version = "1", features = ["derive"] }
32-
humantime = "2"
33-
humantime-serde = "1"
43+
serde = { version = "1", features = ["derive"], optional = true }
44+
serde_yaml = { version = "0.8.17", optional = true }
45+
serde_json = { version = "1.0", optional = true }
46+
toml = { version = "0.5", optional = true }
47+
humantime = { version = "2", optional = true }
48+
humantime-serde = { version = "1", optional = true }
3449
bstr = { version = "1.0", features = ["serde"] }
3550
derive_more = "0.99.17"
3651
eyre = "0.6"
37-
serde_yaml = "0.8.17"
38-
serde_json = "1.0"
39-
schemars = { version = "0.8.11", features = ["preserve_order"] }
40-
toml = "0.5"
52+
schemars = { version = "0.8.11", features = ["preserve_order"], optional = true }
4153
assert_cmd = "2.0"
42-
clap = { version = "4.0", features = ["derive"] }
43-
proc-exit = "1.0"
54+
clap = { version = "4.0", features = ["derive"], optional = true }
55+
proc-exit = { version = "1.0", optional = true}
4456

4557
[dev-dependencies]
4658
snapbox = { version = "0.4.0", features = ["path"] }

src/lib.rs

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,62 @@ use eyre::WrapErr;
88

99
impl TodoList {
1010
pub fn load(path: &std::path::Path) -> eyre::Result<Self> {
11-
let data = std::fs::read_to_string(path)
12-
.wrap_err_with(|| format!("Could not read {}", path.display()))?;
11+
match path.extension().and_then(std::ffi::OsStr::to_str) {
12+
#[cfg(feature = "yaml")]
13+
Some("yaml") | Some("yml") => {
14+
let data = std::fs::read_to_string(path)
15+
.wrap_err_with(|| format!("Could not read {}", path.display()))?;
1316

14-
let dag: Self = match path.extension().and_then(std::ffi::OsStr::to_str) {
15-
Some("yaml") | Some("yml") => serde_yaml::from_str(&data)
16-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
17-
Some("json") => serde_json::from_str(&data)
18-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
19-
Some("toml") => toml::from_str(&data)
20-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
21-
Some(other) => {
22-
return Err(eyre::eyre!("Unknown extension: {:?}", other));
17+
serde_yaml::from_str(&data)
18+
.wrap_err_with(|| format!("Could not parse {}", path.display()))
2319
}
24-
None => {
25-
return Err(eyre::eyre!("No extension for {}", path.display()));
20+
#[cfg(feature = "json")]
21+
Some("json") => {
22+
let data = std::fs::read_to_string(path)
23+
.wrap_err_with(|| format!("Could not read {}", path.display()))?;
24+
25+
serde_json::from_str(&data)
26+
.wrap_err_with(|| format!("Could not parse {}", path.display()))
2627
}
27-
};
28+
#[cfg(feature = "toml")]
29+
Some("toml") => {
30+
let data = std::fs::read_to_string(path)
31+
.wrap_err_with(|| format!("Could not read {}", path.display()))?;
2832

29-
Ok(dag)
33+
toml::from_str(&data)
34+
.wrap_err_with(|| format!("Could not parse {}", path.display()))
35+
}
36+
Some(other) => Err(eyre::eyre!("Unknown extension: {:?}", other)),
37+
None => Err(eyre::eyre!("No extension for {}", path.display())),
38+
}
3039
}
3140

3241
pub fn save(&self, path: &std::path::Path) -> eyre::Result<()> {
33-
let raw: String = match path.extension().and_then(std::ffi::OsStr::to_str) {
34-
Some("yaml") | Some("yml") => serde_yaml::to_string(self)
35-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
36-
Some("json") => serde_json::to_string(self)
37-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
38-
Some("toml") => toml::to_string(self)
39-
.wrap_err_with(|| format!("Could not parse {}", path.display()))?,
40-
Some(other) => {
41-
return Err(eyre::eyre!("Unknown extension: {:?}", other));
42+
match path.extension().and_then(std::ffi::OsStr::to_str) {
43+
#[cfg(feature = "yaml")]
44+
Some("yaml") | Some("yml") => {
45+
let raw = serde_yaml::to_string(self)
46+
.wrap_err_with(|| format!("Could not parse {}", path.display()))?;
47+
std::fs::write(path, &raw)
48+
.wrap_err_with(|| format!("Could not write {}", path.display()))
4249
}
43-
None => {
44-
return Err(eyre::eyre!("No extension for {}", path.display()));
50+
#[cfg(feature = "json")]
51+
Some("json") => {
52+
let raw = serde_json::to_string(self)
53+
.wrap_err_with(|| format!("Could not parse {}", path.display()))?;
54+
std::fs::write(path, &raw)
55+
.wrap_err_with(|| format!("Could not write {}", path.display()))
4556
}
46-
};
47-
48-
std::fs::write(path, &raw)
49-
.wrap_err_with(|| format!("Could not write {}", path.display()))?;
50-
51-
Ok(())
57+
#[cfg(feature = "toml")]
58+
Some("toml") => {
59+
let raw = toml::to_string(self)
60+
.wrap_err_with(|| format!("Could not parse {}", path.display()))?;
61+
std::fs::write(path, &raw)
62+
.wrap_err_with(|| format!("Could not write {}", path.display()))
63+
}
64+
Some(other) => Err(eyre::eyre!("Unknown extension: {:?}", other)),
65+
None => Err(eyre::eyre!("No extension for {}", path.display())),
66+
}
5267
}
5368

5469
pub fn run(self, cwd: &std::path::Path) -> eyre::Result<()> {

src/main.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::io::Write;
2-
31
use clap::Parser;
42
use proc_exit::WithCodeResultExt;
53

@@ -36,13 +34,22 @@ fn run() -> proc_exit::ExitResult {
3634
let mut dag = git_fixture::TodoList::load(input).with_code(proc_exit::Code::CONFIG_ERR)?;
3735
dag.sleep = dag.sleep.or_else(|| args.sleep.map(|s| s.into()));
3836
dag.run(&output).with_code(proc_exit::Code::FAILURE)?;
39-
} else if let Some(schema_path) = args.schema.as_deref() {
40-
let schema = schemars::schema_for!(git_fixture::TodoList);
41-
let schema = serde_json::to_string_pretty(&schema).unwrap();
42-
if schema_path == std::path::Path::new("-") {
43-
std::io::stdout().write_all(schema.as_bytes())?;
44-
} else {
45-
std::fs::write(&schema_path, &schema).with_code(proc_exit::Code::FAILURE)?;
37+
} else if let Some(_schema_path) = args.schema.as_deref() {
38+
#[cfg(feature = "schema")]
39+
{
40+
use std::io::Write;
41+
42+
let schema = schemars::schema_for!(git_fixture::TodoList);
43+
let schema = serde_json::to_string_pretty(&schema).unwrap();
44+
if _schema_path == std::path::Path::new("-") {
45+
std::io::stdout().write_all(schema.as_bytes())?;
46+
} else {
47+
std::fs::write(&_schema_path, &schema).with_code(proc_exit::Code::FAILURE)?;
48+
}
49+
}
50+
#[cfg(not(feature = "schema"))]
51+
{
52+
return Err(eyre::eyre!("schema is unsupported")).with_code(proc_exit::Code::FAILURE);
4653
}
4754
}
4855
Ok(())

src/model.rs

Lines changed: 59 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
2-
#[serde(rename_all = "snake_case")]
3-
#[serde(deny_unknown_fields)]
1+
#[derive(Clone, Debug)]
2+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
4+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
5+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
46
pub struct TodoList {
5-
#[serde(default = "init_default")]
7+
#[cfg_attr(feature = "serde", serde(default = "init_default"))]
68
pub init: bool,
7-
#[serde(default)]
8-
#[serde(serialize_with = "humantime_serde::serialize")]
9-
#[serde(deserialize_with = "humantime_serde::deserialize")]
9+
#[cfg_attr(feature = "serde", serde(default))]
10+
#[cfg_attr(
11+
feature = "serde",
12+
serde(serialize_with = "humantime_serde::serialize")
13+
)]
14+
#[cfg_attr(
15+
feature = "serde",
16+
serde(deserialize_with = "humantime_serde::deserialize")
17+
)]
1018
pub sleep: Option<std::time::Duration>,
11-
#[serde(default)]
19+
#[cfg_attr(feature = "serde", serde(default))]
1220
pub author: Option<String>,
13-
#[serde(default)]
21+
#[cfg_attr(feature = "serde", serde(default))]
1422
pub commands: Vec<Command>,
1523
}
1624

@@ -29,11 +37,11 @@ impl Default for TodoList {
2937
}
3038
}
3139

32-
#[derive(
33-
Clone, Debug, serde::Serialize, serde::Deserialize, derive_more::IsVariant, schemars::JsonSchema,
34-
)]
35-
#[serde(rename_all = "snake_case")]
36-
#[serde(deny_unknown_fields)]
40+
#[derive(Clone, Debug, derive_more::IsVariant)]
41+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
43+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
44+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
3745
pub enum Command {
3846
Label(Label),
3947
Reset(Reference),
@@ -50,23 +58,25 @@ impl From<Tree> for Command {
5058
}
5159
}
5260

53-
#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
54-
#[serde(rename_all = "snake_case")]
55-
#[serde(deny_unknown_fields)]
61+
#[derive(Default, Clone, Debug)]
62+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
63+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
64+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
65+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
5666
pub struct Tree {
5767
pub tracked: std::collections::HashMap<std::path::PathBuf, FileContent>,
58-
#[serde(default)]
68+
#[cfg_attr(feature = "serde", serde(default))]
5969
pub message: Option<String>,
60-
#[serde(default)]
70+
#[cfg_attr(feature = "serde", serde(default))]
6171
pub author: Option<String>,
6272
}
6373

64-
#[derive(
65-
Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema, derive_more::IsVariant,
66-
)]
67-
#[serde(rename_all = "snake_case")]
68-
#[serde(untagged)]
69-
#[serde(deny_unknown_fields)]
74+
#[derive(Clone, Debug, derive_more::IsVariant)]
75+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
77+
#[cfg_attr(feature = "serde", serde(untagged))]
78+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
79+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
7080
pub enum FileContent {
7181
Binary(Vec<u8>),
7282
Text(String),
@@ -99,22 +109,24 @@ impl<'d> From<&'d str> for FileContent {
99109
}
100110
}
101111

102-
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
103-
#[serde(rename_all = "snake_case")]
104-
#[serde(deny_unknown_fields)]
112+
#[derive(Clone, Debug)]
113+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
114+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
115+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
116+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
105117
pub struct Merge {
106118
pub base: Vec<Reference>,
107-
#[serde(default)]
119+
#[cfg_attr(feature = "serde", serde(default))]
108120
pub message: Option<String>,
109-
#[serde(default)]
121+
#[cfg_attr(feature = "serde", serde(default))]
110122
pub author: Option<String>,
111123
}
112124

113-
#[derive(
114-
Clone, Debug, serde::Serialize, serde::Deserialize, derive_more::IsVariant, schemars::JsonSchema,
115-
)]
116-
#[serde(rename_all = "snake_case")]
117-
#[serde(deny_unknown_fields)]
125+
#[derive(Clone, Debug, derive_more::IsVariant)]
126+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
127+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
128+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
129+
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
118130
pub enum Reference {
119131
Branch(Branch),
120132
Tag(Tag),
@@ -139,19 +151,10 @@ impl From<Label> for Reference {
139151
}
140152
}
141153

142-
#[derive(
143-
Clone,
144-
Debug,
145-
PartialEq,
146-
Eq,
147-
PartialOrd,
148-
Ord,
149-
Hash,
150-
serde::Serialize,
151-
serde::Deserialize,
152-
schemars::JsonSchema,
153-
)]
154-
#[serde(transparent)]
154+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
155+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
156+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
157+
#[cfg_attr(feature = "serde", serde(transparent))]
155158
pub struct Label(String);
156159

157160
impl Label {
@@ -192,19 +195,10 @@ impl std::borrow::Borrow<str> for Label {
192195
}
193196
}
194197

195-
#[derive(
196-
Clone,
197-
Debug,
198-
PartialEq,
199-
Eq,
200-
PartialOrd,
201-
Ord,
202-
Hash,
203-
serde::Serialize,
204-
serde::Deserialize,
205-
schemars::JsonSchema,
206-
)]
207-
#[serde(transparent)]
198+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
199+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
200+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
201+
#[cfg_attr(feature = "serde", serde(transparent))]
208202
pub struct Branch(String);
209203

210204
impl Branch {
@@ -245,19 +239,10 @@ impl std::borrow::Borrow<str> for Branch {
245239
}
246240
}
247241

248-
#[derive(
249-
Clone,
250-
Debug,
251-
PartialEq,
252-
Eq,
253-
PartialOrd,
254-
Ord,
255-
Hash,
256-
serde::Serialize,
257-
serde::Deserialize,
258-
schemars::JsonSchema,
259-
)]
260-
#[serde(transparent)]
242+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
243+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
244+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
245+
#[cfg_attr(feature = "serde", serde(transparent))]
261246
pub struct Tag(String);
262247

263248
impl Tag {

tests/fixtures.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg(feature = "yaml")]
2+
13
#[track_caller]
24
fn assert_success(name: &str) {
35
let path = std::path::PathBuf::from(format!("tests/fixtures/{name}.yml"));

0 commit comments

Comments
 (0)