Решение на Форматиране на импорти от Иван Стойнев
Резултати
- 13 точки от тестове
- 0 бонус точки
- 13 точки общо
- 13 успешни тест(а)
- 7 неуспешни тест(а)
Код
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 unique_imports: Vec<String> = imports
.iter()
.map(|import| import.0.join("::"))
.collect();
unique_imports.sort();
unique_imports.dedup();
if matches!(order, Order::Original) {
let mut original_order: Vec<String> = Vec::new();
for import in imports {
let path = import.0.join("::");
if !original_order.contains(&path) {
original_order.push(path);
}
}
original_order
} else {
unique_imports
}
}
use std::collections::BTreeMap;
#[derive(Default)]
struct Tree {
children: BTreeMap<String, Tree>,
}
impl Tree {
fn insert(&mut self, path: &[&str]) {
if path.is_empty() {
return;
}
let (head, tail) = path.split_first().unwrap();
self.children.entry(head.to_string()).or_default().insert(tail);
}
fn format(&self, indent: usize) -> String {
let mut result = String::new();
let mut keys: Vec<&String> = self.children.keys().collect();
keys.sort();
for key in keys {
if self.children[key].children.is_empty() {
result.push_str(&" ".repeat(indent));
result.push_str(key);
result.push_str(",\n");
} else {
result.push_str(&" ".repeat(indent));
result.push_str(key);
result.push_str("::{\n");
result.push_str(&self.children[key].format(indent + 4));
result.push_str(&" ".repeat(indent));
result.push_str("},\n");
}
}
result
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
use std::collections::BTreeMap;
#[derive(Default)]
struct Tree {
children: BTreeMap<String, Tree>,
}
impl Tree {
fn insert(&mut self, path: &[&str]) {
if let Some((head, tail)) = path.split_first() {
self.children
.entry(head.to_string())
.or_default()
.insert(tail);
}
}
fn format(&self, indent: usize) -> String {
let mut result = String::new();
for (key, child) in &self.children {
result.push_str(&" ".repeat(indent));
if child.children.is_empty() {
result.push_str(key);
result.push_str(",\n");
} else {
result.push_str(key);
result.push_str("::{\n");
result.push_str(&child.format(indent + 4));
result.push_str(&" ".repeat(indent));
result.push_str("},\n");
}
}
result
}
}
let mut crate_trees: BTreeMap<String, Tree> = BTreeMap::new();
for import in imports {
if let Some((crate_name, path)) = import.0.split_first() {
crate_trees
.entry(crate_name.to_string())
.or_default()
.insert(path);
}
}
let mut crate_list: Vec<(&String, &Tree)> = crate_trees.iter().collect();
if matches!(order, Order::Original) {
crate_list.sort_by_key(|&(key, _)| imports.iter().position(|imp| imp.0[0] == key));
}
crate_list
.into_iter()
.map(|(crate_name, tree)| {
let mut result = String::new();
result.push_str(&format!("{}::{{\n", crate_name));
result.push_str(&tree.format(4));
result.push_str("}\n");
result
})
.collect()
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20241203-1739405-l1wpeh/solution) warning: the item `BTreeMap` is imported redundantly --> src/lib.rs:72:9 | 31 | use std::collections::BTreeMap; | -------------------------- the item `BTreeMap` is already imported here ... 72 | use std::collections::BTreeMap; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: field `children` is never read --> src/lib.rs:35:5 | 34 | struct Tree { | ---- field in this struct 35 | children: BTreeMap<String, Tree>, | ^^^^^^^^ | = note: `#[warn(dead_code)]` on by default warning: associated function `insert` is never used --> src/lib.rs:39:8 | 39 | fn insert(&mut self, path: &[&str]) { | ^^^^^^ warning: associated function `format` is never used --> src/lib.rs:47:8 | 47 | fn format(&self, indent: usize) -> String { | ^^^^^^ warning: `solution` (lib) generated 4 warnings Finished test [unoptimized + debuginfo] target(s) in 2.03s 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_only_crate ... FAILED test solution_test::test_nested_original ... FAILED test solution_test::test_nested_original_2 ... FAILED test solution_test::test_nested_original_duplicates ... FAILED test solution_test::test_nested_original_multi_crate ... FAILED test solution_test::test_nested_original_self ... FAILED test solution_test::test_nested_sorted ... ok test solution_test::test_nested_sorted_2 ... 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 ... FAILED 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}\n"]`, right: `["my_crate\n"]`', tests/solution_test.rs:132:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- solution_test::test_nested_original stdout ---- thread 'solution_test::test_nested_original' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n B2,\n B1,\n },\n a,\n}\n"]`', tests/solution_test.rs:173:5 ---- solution_test::test_nested_original_2 stdout ---- thread 'solution_test::test_nested_original_2' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a::{\n A1,\n inner::{\n I1,\n },\n },\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n B2,\n B1,\n },\n a::{\n inner::{\n I1,\n },\n A1,\n },\n}\n"]`', tests/solution_test.rs:198:5 ---- solution_test::test_nested_original_duplicates stdout ---- thread 'solution_test::test_nested_original_duplicates' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n B2,\n B1,\n },\n a,\n}\n"]`', tests/solution_test.rs:283:5 ---- solution_test::test_nested_original_multi_crate stdout ---- thread 'solution_test::test_nested_original_multi_crate' panicked at 'assertion failed: `(left == right)` left: `["crate::{\n a,\n b,\n}\n", "std::{\n string::{\n String,\n },\n}\n"]`, right: `["crate::{\n b,\n a,\n}\n", "std::{\n string::{\n String,\n },\n}\n"]`', tests/solution_test.rs:385:5 ---- solution_test::test_nested_original_self stdout ---- thread 'solution_test::test_nested_original_self' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n self,\n B2,\n B1,\n },\n a,\n}\n"]`', tests/solution_test.rs:334:5 ---- solution_test::test_nested_sorted_self stdout ---- thread 'solution_test::test_nested_sorted_self' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n a,\n b::{\n self,\n B1,\n B2,\n },\n c,\n}\n"]`', tests/solution_test.rs:360:5 failures: solution_test::test_nested_only_crate solution_test::test_nested_original solution_test::test_nested_original_2 solution_test::test_nested_original_duplicates solution_test::test_nested_original_multi_crate solution_test::test_nested_original_self solution_test::test_nested_sorted_self test result: FAILED. 13 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass `--test solution_test`