Решение на Форматиране на импорти от Иван Панайотов

Обратно към всички решения

Към профила на Иван Панайотов

Резултати

  • 19 точки от тестове
  • 1 бонус точка
  • 20 точки общо
  • 19 успешни тест(а)
  • 1 неуспешни тест(а)

Код

pub struct Import<'a>(pub &'a [&'a str]);
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut result = Vec::new();
for import in imports {
let path = import.0.join("::");
if !result.contains(&path) {
result.push(path);
}
}
if let Order::Sorted = order {
result.sort();
}
result.into_iter().map(String::from).collect()
}
struct Node {
pub value: String,
pub children: Vec<Box<Node>>,
pub is_used: bool,
}
impl Node {
fn new(value: String) -> Self {
Node {
value,
children: Vec::new(),
is_used: false,
}
}
// Добави наследник само ако вече няма такъв
fn add_child(&mut self, value: String) {
if (self.children.iter_mut().find(|c| c.value == value)).is_none() {
self.children.push(Box::new(Node::new(value)));
}
}
}
struct Tree {
root: Box<Node>,
}
impl Tree {
fn new() -> Self {
Tree {
root: Box::new(Node::new("1".to_string())), // Тъй като не може да има самостоятелни цифри в имената, ще използвам "1" за корен
}
}
fn insert(&mut self, path: &Import) {
let path = path.0;
let mut current = &mut self.root;
for i in 0..path.len() {
current.add_child(path[i].to_string());
current = current
.children
.iter_mut()
.find(|c| c.value == path[i])
.unwrap();
}
current.is_used = true;
}
fn to_string(&self) -> Vec<String> {
let mut crates = Vec::new();
for child in &self.root.children {
crates.push(Tree::format_node(child, 0, child.is_used));
}
return crates;
}
fn format_node(node: &Node, indent: usize, include_parent_node: bool) -> String {
let mut result = format!("{}{}", " ".repeat(indent), node.value);
if node.children.is_empty() {
return format!("{},\n", result);
} else {
result.push_str("::{\n");
if include_parent_node {
result.push_str(&format!("{}{}", " ".repeat(indent + 4), "self,\n"));
}
for child in &node.children {
result.push_str(Tree::format_node(child, indent + 4, child.is_used).as_str());
}
result.push_str(&format!("{}}}", " ".repeat(indent)));
// Не добавям запетаята за най-горния елемент
if indent != 0 {
result.push_str(",");
}
result.push_str("\n");
return result;
}
}
fn order(&mut self) {
Tree::order_node(&mut self.root);
}
fn order_node(node: &mut Node) {
node.children.sort_by(|a, b| a.value.cmp(&b.value));
for child in &mut node.children {
Tree::order_node(child);
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new();
for import in imports {
tree.insert(import);
}
if let Order::Sorted = order {
tree.order();
}
tree.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
];
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"my_crate::a",
"my_crate::b::B1",
"my_crate::b::B2",
"my_crate::c",
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
)]
);
}
#[test]
fn test_format_flat() {
let imports = vec![
Import(&["std", "vec", "IntoIter"]),
Import(&["std", "collections", "hash_map"]),
Import(&["std", "vec", "IntoIter"]),
];
let result = format_flat(&imports, Order::Original);
assert_eq!(
result,
vec!["std::vec::IntoIter", "std::collections::hash_map",]
);
let imports = vec![
Import(&["std", "vec", "IntoIter"]),
Import(&["std", "collections", "hash_map"]),
Import(&["std", "vec", "IntoIter"]),
];
let result = format_flat(&imports, Order::Sorted);
assert_eq!(
result,
vec!["std::collections::hash_map", "std::vec::IntoIter",]
);
}
#[test]
fn test_format_nested() {
let imports = vec![
Import(&["std", "vec", "Vec"]),
Import(&["std", "vec", "IntoIter"]),
Import(&["std", "iter", "Iterator"]),
];
let result = format_nested(&imports, Order::Original);
assert_eq!(result, vec![
"std::{\n vec::{\n Vec,\n IntoIter,\n },\n iter::{\n Iterator,\n },\n}\n",
]);
let imports = vec![
Import(&["std", "iter", "Iterator"]),
Import(&["std", "vec", "Vec"]),
Import(&["std", "vec", "IntoIter"]),
];
let result = format_nested(&imports, Order::Sorted);
assert_eq!(result, vec![
"std::{\n iter::{\n Iterator,\n },\n vec::{\n IntoIter,\n Vec,\n },\n}\n",
]);
let imports = vec![
Import(&["foo", "b", "B2"]),
Import(&["foo", "a", "A1"]),
Import(&["foo", "b", "B1"]),
];
let result = format_nested(&imports, Order::Original);
assert_eq!(result, vec![
"foo::{\n b::{\n B2,\n B1,\n },\n a::{\n A1,\n },\n}\n",
]);
let imports = vec![
Import(&["foo", "b", "B2"]),
Import(&["foo", "a", "A1"]),
Import(&["foo", "b", "B1"]),
];
let result = format_nested(&imports, Order::Sorted);
assert_eq!(result, vec![
"foo::{\n a::{\n A1,\n },\n b::{\n B1,\n B2,\n },\n}\n",
]);
let imports = vec![Import(&["std", "a"]), Import(&["foo", "b"])];
let result = format_nested(&imports, Order::Original);
assert_eq!(
result,
vec![
String::from("std::{\n a,\n}\n"),
String::from("foo::{\n b,\n}\n"),
]
);
let result = format_nested(&imports, Order::Sorted);
assert_eq!(
result,
vec![
String::from("foo::{\n b,\n}\n"),
String::from("std::{\n a,\n}\n"),
]
);
let imports = vec![Import(&["std", "b", "B1"]), Import(&["std", "b"])];
let result = format_nested(&imports, Order::Sorted);
assert_eq!(
result,
vec!["std::{\n b::{\n self,\n B1,\n },\n}\n",]
);
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20241203-1739405-9zx3t2/solution)
    Finished test [unoptimized + debuginfo] target(s) in 1.11s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 20 tests
test solution_test::test_flat_empty ... ok
test solution_test::test_flat_multi_crate ... ok
test solution_test::test_flat_original ... ok
test solution_test::test_flat_original_duplicates ... ok
test solution_test::test_flat_sorted ... ok
test solution_test::test_flat_sorted_duplicates ... ok
test solution_test::test_nested_basic ... ok
test solution_test::test_nested_deep ... ok
test solution_test::test_nested_empty ... ok
test solution_test::test_nested_original ... ok
test solution_test::test_nested_only_crate ... FAILED
test solution_test::test_nested_original_2 ... ok
test solution_test::test_nested_original_duplicates ... ok
test solution_test::test_nested_original_multi_crate ... ok
test solution_test::test_nested_original_self ... ok
test solution_test::test_nested_sorted_2 ... ok
test solution_test::test_nested_sorted ... ok
test solution_test::test_nested_sorted_duplicates ... ok
test solution_test::test_nested_sorted_multi_crate ... ok
test solution_test::test_nested_sorted_self ... ok

failures:

---- solution_test::test_nested_only_crate stdout ----
thread 'solution_test::test_nested_only_crate' panicked at 'assertion failed: `(left == right)`
  left: `["my_crate,\n"]`,
 right: `["my_crate\n"]`', tests/solution_test.rs:132:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    solution_test::test_nested_only_crate

test result: FAILED. 19 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--test solution_test`

История (1 версия и 0 коментара)

Иван качи първо решение на 03.12.2024 12:01 (преди 9 месеца)