use alef_core::hash::{self, CommentStyle};
use alef_core::template_versions as tv;
#[allow(clippy::too_many_arguments)]
pub fn render_cargo_toml(
crate_name: &str,
dep_name: &str,
crate_path: &str,
needs_serde_json: bool,
needs_mock_server: bool,
needs_http_tests: bool,
needs_tokio: bool,
needs_tower_http: bool,
dep_mode: crate::config::DependencyMode,
version: Option<&str>,
features: &[String],
) -> String {
let e2e_name = format!("{dep_name}-e2e-rust");
let effective_features: Vec<&str> = features.iter().map(|s| s.as_str()).collect();
let features_str = if effective_features.is_empty() {
String::new()
} else {
format!(", default-features = false, features = {:?}", effective_features)
};
let dep_spec = match dep_mode {
crate::config::DependencyMode::Registry => {
let ver = version.unwrap_or("0.1.0");
if crate_name != dep_name {
format!("{dep_name} = {{ package = \"{crate_name}\", version = \"{ver}\"{features_str} }}")
} else if effective_features.is_empty() {
format!("{dep_name} = \"{ver}\"")
} else {
format!("{dep_name} = {{ version = \"{ver}\"{features_str} }}")
}
}
crate::config::DependencyMode::Local => {
if crate_name != dep_name {
format!("{dep_name} = {{ package = \"{crate_name}\", path = \"{crate_path}\"{features_str} }}")
} else if effective_features.is_empty() {
format!("{dep_name} = {{ path = \"{crate_path}\" }}")
} else {
format!("{dep_name} = {{ path = \"{crate_path}\"{features_str} }}")
}
}
};
let effective_needs_serde_json = needs_serde_json || needs_mock_server || needs_http_tests;
let serde_line = if effective_needs_serde_json {
"\nserde_json = \"1\""
} else {
""
};
let needs_axum = needs_mock_server || needs_http_tests;
let mock_lines = if needs_axum {
let mut lines = format!(
"\naxum = \"{axum}\"\nserde = {{ version = \"1\", features = [\"derive\"] }}\nwalkdir = \"{walkdir}\"",
axum = tv::cargo::AXUM,
walkdir = tv::cargo::WALKDIR,
);
if needs_mock_server {
lines.push_str(&format!(
"\ntokio-stream = \"{tokio_stream}\"",
tokio_stream = tv::cargo::TOKIO_STREAM
));
}
if needs_http_tests {
lines.push_str("\naxum-test = \"20\"\nbytes = \"1\"");
}
if needs_tower_http {
lines.push_str(&format!(
"\ntower-http = {{ version = \"{tower_http}\", features = [\"cors\", \"fs\"] }}\ntempfile = \"{tempfile}\"",
tower_http = tv::cargo::TOWER_HTTP,
tempfile = tv::cargo::TEMPFILE,
));
}
lines
} else {
String::new()
};
let mut machete_ignored: Vec<&str> = Vec::new();
if effective_needs_serde_json {
machete_ignored.push("\"serde_json\"");
}
if needs_axum {
machete_ignored.push("\"axum\"");
machete_ignored.push("\"serde\"");
machete_ignored.push("\"walkdir\"");
}
if needs_mock_server {
machete_ignored.push("\"tokio-stream\"");
}
if needs_http_tests {
machete_ignored.push("\"axum-test\"");
machete_ignored.push("\"bytes\"");
}
if needs_tower_http {
machete_ignored.push("\"tower-http\"");
machete_ignored.push("\"tempfile\"");
}
let machete_section = if machete_ignored.is_empty() {
String::new()
} else {
format!(
"\n[package.metadata.cargo-machete]\nignored = [{}]\n",
machete_ignored.join(", ")
)
};
let tokio_line = if needs_tokio {
"\ntokio = { version = \"1\", features = [\"full\"] }"
} else {
""
};
let bin_section = if needs_mock_server || needs_http_tests {
"\n[[bin]]\nname = \"mock-server\"\npath = \"src/main.rs\"\n"
} else {
""
};
let header = hash::header(CommentStyle::Hash);
format!(
r#"{header}
[workspace]
[package]
name = "{e2e_name}"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
{bin_section}
[dependencies]
{dep_spec}{serde_line}{mock_lines}{tokio_line}
{machete_section}"#
)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::DependencyMode;
#[test]
fn render_cargo_toml_local_no_features_produces_path_dep() {
let out = render_cargo_toml(
"my-crate",
"my_crate",
"../../crates/my-crate",
false,
false,
false,
false,
false,
DependencyMode::Local,
None,
&[],
);
assert!(
out.contains("my_crate = { package = \"my-crate\", path = \"../../crates/my-crate\" }"),
"got:\n{out}"
);
assert!(out.contains("edition = \"2021\""));
}
#[test]
fn render_cargo_toml_local_same_name_produces_simple_path_dep() {
let out = render_cargo_toml(
"my_crate",
"my_crate",
"../../crates/my_crate",
false,
false,
false,
false,
false,
DependencyMode::Local,
None,
&[],
);
assert!(
out.contains("my_crate = { path = \"../../crates/my_crate\" }"),
"got:\n{out}"
);
}
}