use crate::cargo::unify_types::UnifiedDep;
use toml_edit::{InlineTable, Item, Value};
use super::fields::build_feature_array;
pub fn build_dep_entry(dep: &UnifiedDep) -> Item {
if dep.features.is_empty() && dep.default_features && dep.path.is_none() {
let mut value = Value::from(dep.version_req.to_string());
value.decor_mut().set_suffix(" #unified");
return Item::Value(value);
}
let mut table = InlineTable::new();
if let Some(ref path) = dep.path {
table.insert("path", Value::from(path.display().to_string()));
if dep.version_req.to_string() != "*" {
table.insert("version", Value::from(dep.version_req.to_string()));
}
} else {
table.insert("version", Value::from(dep.version_req.to_string()));
}
if !dep.default_features {
table.insert("default-features", Value::from(false));
}
if !dep.features.is_empty() {
table.insert("features", build_feature_array(&dep.features));
}
let mut value = Value::InlineTable(table);
value.decor_mut().set_suffix(" #unified");
Item::Value(value)
}
pub fn build_workspace_dep_entry<S: AsRef<str>>(local_features: Option<&[S]>, is_optional: bool) -> Item {
let mut table = InlineTable::new();
table.insert("workspace", Value::from(true));
if let Some(features) = local_features
&& !features.is_empty()
{
table.insert("features", build_feature_array(features));
}
if is_optional {
table.insert("optional", Value::from(true));
}
let mut value = Value::InlineTable(table);
value.decor_mut().set_suffix(" #unified");
Item::Value(value)
}
pub fn build_transitive_entry<S: AsRef<str>>(features: &[S]) -> Item {
let mut table = InlineTable::new();
table.insert("workspace", Value::from(true));
if !features.is_empty() {
table.insert("features", build_feature_array(features));
}
let mut value = Value::InlineTable(table);
value.decor_mut().set_suffix(" #unified");
Item::Value(value)
}
pub fn build_versioned_dep_entry<S: AsRef<str>>(version: &semver::Version, features: &[S]) -> Item {
if features.is_empty() {
let mut value = Value::from(format!("^{}", version));
value.decor_mut().set_suffix(" #unified");
return Item::Value(value);
}
let mut table = InlineTable::new();
table.insert("version", Value::from(format!("^{}", version)));
table.insert("default-features", Value::from(false));
table.insert("features", build_feature_array(features));
let mut value = Value::InlineTable(table);
value.decor_mut().set_suffix(" #unified");
Item::Value(value)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cargo::unify_types::UnifiedDep;
use std::path::PathBuf;
use std::sync::Arc;
use super::super::fields::extract_features;
use super::super::workspace_ref::is_workspace_dep;
fn create_test_dep(name: &str, version: &str) -> UnifiedDep {
UnifiedDep {
name: Arc::from(name),
version_req: version.parse().unwrap(),
features: vec![],
default_features: true,
used_by: vec![Arc::from("test-crate")],
target: None,
path: None,
}
}
#[test]
fn test_build_dep_entry_simple() {
let dep = create_test_dep("serde", "1.0");
let entry = build_dep_entry(&dep);
assert!(entry.as_str().is_some());
assert_eq!(entry.as_str().unwrap(), "^1.0");
}
#[test]
fn test_build_dep_entry_with_features() {
let mut dep = create_test_dep("serde", "1.0");
dep.features = vec![Arc::from("derive")];
let entry = build_dep_entry(&dep);
assert!(entry.as_inline_table().is_some());
let features = extract_features(&entry).unwrap();
assert_eq!(features, vec!["derive"]);
}
#[test]
fn test_build_dep_entry_with_path() {
let mut dep = create_test_dep("local-crate", "0.1.0");
dep.path = Some(PathBuf::from("../local-crate"));
let entry = build_dep_entry(&dep);
let table = entry.as_inline_table().unwrap();
assert!(table.contains_key("path"));
assert_eq!(table.get("path").unwrap().as_str().unwrap(), "../local-crate");
}
#[test]
fn test_build_dep_entry_no_default_features() {
let mut dep = create_test_dep("tokio", "1.0");
dep.default_features = false;
let entry = build_dep_entry(&dep);
let table = entry.as_inline_table().unwrap();
assert!(!table.get("default-features").unwrap().as_bool().unwrap());
}
#[test]
fn test_build_workspace_dep_entry_simple() {
let entry = build_workspace_dep_entry::<String>(None, false);
assert!(is_workspace_dep(&entry));
assert!(entry.as_inline_table().is_some());
}
#[test]
fn test_build_workspace_dep_entry_with_features() {
let features = ["extra".to_string()];
let entry = build_workspace_dep_entry(Some(&features[..]), false);
assert!(is_workspace_dep(&entry));
let features = extract_features(&entry).unwrap();
assert_eq!(features, vec!["extra"]);
}
#[test]
fn test_build_workspace_dep_entry_optional() {
let entry = build_workspace_dep_entry::<String>(None, true);
assert!(is_workspace_dep(&entry));
let table = entry.as_inline_table().unwrap();
assert!(table.get("optional").unwrap().as_bool().unwrap());
}
#[test]
fn test_build_transitive_entry() {
let features = ["feature1".to_string(), "feature2".to_string()];
let entry = build_transitive_entry(&features);
assert!(is_workspace_dep(&entry));
let extracted = extract_features(&entry).unwrap();
assert_eq!(extracted, vec!["feature1", "feature2"]);
}
}