Решение на Форматиране на импорти от Венцислав Монев

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

Към профила на Венцислав Монев

Резултати

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

Код

pub struct Import<'a>(pub &'a [&'a str]);
pub enum Order {
Original,
Sorted,
}
fn format_flat_vec_fill(imports: &[Import]) ->Vec<String> {
let mut result = Vec::new();
for import in imports.iter() {
let import_string = import.0.join("::");
if !result.contains(&import_string) {
result.push(import_string);
}
}
result
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut result:Vec<String> = format_flat_vec_fill(imports);
match order {
Order::Original => {
result
},
Order::Sorted => {
result.sort_unstable();
result
},
}
}
fn format_nested_tree_fill(imports:&[Import]) -> Tree {
let mut tree = Tree::new();
for import in imports {
tree.add_import(import);
}
tree
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let tree = format_nested_tree_fill(imports);
let mut result:Vec<String> = Vec::new();
match order {
Order::Original => {
for child in tree.root.children.iter() {
result.push(child.format_nested());
}
},
Order::Sorted => {
let mut sorted_children:Vec<&Box<Node>> = tree.root.children.iter().collect();
sorted_children.sort_unstable_by(|a,b| a.value.cmp(&b.value));
for child in sorted_children.iter() {
result.push(child.format_nested_sort());
}
},
}
result
}
struct Tree{
root:Box<Node>,
}
struct Node {
value:String,
is_included:bool,
children:Vec<Box<Node>>,
}
impl Node {
fn new(value:&str) -> Node {
Node {
value: value.to_string(),
is_included:false,
children:Vec::new(),
}
}
fn add_child(&mut self ,child:Box<Node>){
self.children.push(child);
}
fn set_include(&mut self) {
self.is_included=true;
}
fn contains_child(&self, value:&str) -> bool {
for child in &self.children {
if child.value == value {
return true;
}
}
false
}
fn get_child_mut(&mut self, value:&str) ->Option<&mut Box<Node>> {
for child in &mut self.children {
if child.value==value {
return Some(child);
}
}
None
}
fn format_nested_sort(&self) -> String{
self.format_sorted_recursion(0)
}
fn format_nested(&self) -> String {
self.format_recursion(0)
}
fn format_leaf(&self, indent:usize) -> String {
format!("{:>indent$}{},\n", "", self.value, indent=indent)
}
fn format_opening(&self, indent: usize) -> String {
let mut x = format!("{:>indent$}{}::{{\n", "", self.value, indent = indent);
if self.is_included {
x.push_str(&format!("{:>indent$}{},\n", "", "self", indent=indent+4));
}
x
}
fn format_closing(&self, indent: usize) -> String {
let mut x=format!("{:>indent$}}}", "", indent = indent);
if indent==0 {
x.push_str("\n");
}
else {
x.push_str(",\n");
}
x
}
fn format_sorted_recursion(&self, indent:usize) -> String {
let mut result = String::new();
if self.children.is_empty() {
result.push_str(&self.format_leaf(indent));
}
else {
result.push_str(&self.format_opening(indent));
let mut sorted_children:Vec<&Box<Node>> = self.children.iter().collect();
sorted_children.sort_unstable_by(|a,b| a.value.cmp(&b.value));
for child in sorted_children {
result.push_str(&child.format_sorted_recursion(indent+4));
}
result.push_str(&self.format_closing(indent));
}
result
}
fn format_recursion(&self, indent: usize) -> String {
let mut result = String::new();
if self.children.is_empty() {
result.push_str(&self.format_leaf(indent));
}
else {
result.push_str(&self.format_opening(indent));
for child in self.children.iter() {
result.push_str(&child.format_recursion(indent + 4));
}
result.push_str(&self.format_closing(indent));
}
result
}
}
impl Tree {
fn new() -> Tree {
Tree {
root:Box::new(Node::new("")),
}
}
fn add_import(&mut self, import:&Import) {
let mut curr_node = &mut self.root;
for (i,lib) in import.0.iter().enumerate() {
if !curr_node.contains_child(*lib) {
let new_node= Box::new(Node::new(*lib));
curr_node.add_child(new_node);
}
curr_node = curr_node.get_child_mut(*lib).unwrap();
if i==import.0.len() -1 {
curr_node.set_include();
}
}
}
}
#[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_new_node() {
let node = Node::new("test_value");
assert_eq!(node.value, "test_value");
assert_eq!(node.is_included, false);
assert!(node.children.is_empty());
}
#[test]
fn test_add_child_node() {
let mut root = Node::new("root");
let child = Node::new("child");
assert_eq!(root.children.len(), 0);
root.add_child(Box::new(child));
assert_eq!(root.children.len(), 1);
assert_eq!(root.children[0].value, "child");
}
#[test]
fn test_set_include_node() {
let mut root = Node::new("root");
assert_eq!(root.is_included, false);
root.set_include();
assert_eq!(root.is_included, true);
}
#[test]
fn test_contains_child_node() {
let mut root = Node::new("root");
let child = Box::new(Node::new("child"));
let child1 = Box::new(Node::new("child1"));
let child2 = Box::new(Node::new("child2"));
root.add_child(child);
root.add_child(child1);
root.add_child(child2);
assert_eq!(root.contains_child("child"),true);
assert_eq!(root.contains_child("child1"),true);
assert_eq!(root.contains_child("child2"),true);
}
#[test]
fn test_get_child_mut_node() {
let mut root = Node::new("root");
// Add children to the root
root.add_child(Box::new(Node::new("child1")));
root.add_child(Box::new(Node::new("child2")));
// Get a mutable reference to "child1"
if let Some(child_mut) = root.get_child_mut("child1") {
assert_eq!(child_mut.value, "child1");
// Modify the value of the child
child_mut.value = "modified_child1".to_string();
} else {
panic!("Child 'child1' not found");
}
// Ensure the value was updated
assert_eq!(root.children[0].value, "modified_child1");
// Attempt to get a non-existent child
let non_existent = root.get_child_mut("non_existent");
assert!(non_existent.is_none());
}
#[test]
fn test_format_flat() {
let imports = &[
Import(&["std", "io", "prelude"]),
Import(&["std", "io", "BufReader"]),
Import(&["std", "fs", "File"]),
Import(&["std", "fs"]),
Import(&["asd", "123", "qwe","xyz"])
];
assert_eq!(
format_flat(imports, Order::Original),
&[
"std::io::prelude",
"std::io::BufReader",
"std::fs::File",
"std::fs",
"asd::123::qwe::xyz",
]
);
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"asd::123::qwe::xyz",
"std::fs",
"std::fs::File",
"std::io::BufReader",
"std::io::prelude",
]
);
}
#[test]
fn test_format_nested() {
let imports = &[
Import(&["std", "io", "prelude"]),
Import(&["std", "io", "BufReader"]),
Import(&["std", "fs", "File"]),
Import(&["std", "fs"]),
Import(&["asd", "123", "qwe","xyz"])
];
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"std::{\n",
" io::{\n",
" prelude,\n",
" BufReader,\n",
" },\n",
" fs::{\n",
" self,\n",
" File,\n",
" },\n",
"}\n",
),
concat!(
"asd::{\n",
" 123::{\n",
" qwe::{\n",
" xyz,\n",
" },\n",
" },\n",
"}\n",
)
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"asd::{\n",
" 123::{\n",
" qwe::{\n",
" xyz,\n",
" },\n",
" },\n",
"}\n",
),
concat!(
"std::{\n",
" fs::{\n",
" self,\n",
" File,\n",
" },\n",
" io::{\n",
" BufReader,\n",
" prelude,\n",
" },\n",
"}\n",
)
]
);
}
#[test]
fn test_tree() {
let mut tree = Tree::new();
let import1 = Import(&["std", "io", "prelude"]);
let import2 = Import(&["std", "io", "BufReader"]);
let import3 = Import(&["std", "fs", "File"]);
let import4 = Import(&["asd", "123", "qwe","xyz"]);
tree.add_import(&import1);
tree.add_import(&import2);
tree.add_import(&import3);
tree.add_import(&import4);
assert!(!tree.root.is_included);
assert!(tree.root.contains_child("std"));
assert!(tree.root.contains_child("asd"));
assert!(tree.root.children.len()==2);
let std_node = tree.root.get_child_mut("std").unwrap();
assert!(!std_node.is_included);
assert!(std_node.contains_child("io"));
assert!(std_node.children.len()==2);
let io_node = std_node.get_child_mut("io").unwrap();
assert!(!io_node.is_included);
assert!(io_node.contains_child("prelude"));
assert!(io_node.contains_child("BufReader"));
assert!(io_node.children.len()==2);
let prelude_node = io_node.get_child_mut("prelude").unwrap();
assert!(prelude_node.children.len()==0);
assert!(prelude_node.is_included);
let buf_reader_node = io_node.get_child_mut("BufReader").unwrap();
assert!(buf_reader_node.children.len()==0);
assert!(buf_reader_node.is_included);
assert!(std_node.contains_child("fs"));
let fs_node = std_node.get_child_mut("fs").unwrap();
assert!(fs_node.contains_child("File"));
assert!(fs_node.children.len()==1);
let file = fs_node.get_child_mut("File").unwrap();
assert!(file.children.len()==0);
assert!(file.is_included);
let asd_node = tree.root.get_child_mut("asd").unwrap();
assert!(asd_node.contains_child("123"));
let a123_node = asd_node.get_child_mut("123").unwrap();
assert!(!a123_node.is_included);
assert!(a123_node.contains_child("qwe"));
let qwe_node = a123_node.get_child_mut("qwe").unwrap();
assert!(qwe_node.contains_child("xyz"));
let xyz_node = qwe_node.get_child_mut("xyz").unwrap();
assert!(!xyz_node.contains_child(""));
assert!(xyz_node.children.len()==0);
assert!(xyz_node.is_included);
}

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

Compiling solution v0.1.0 (/tmp/d20241203-1739405-11j0md3/solution)
    Finished test [unoptimized + debuginfo] target(s) in 1.81s
     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 ... 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 ... 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 ... ok
test solution_test::test_nested_original_2 ... 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 коментара)

Венцислав качи първо решение на 02.12.2024 20:14 (преди 9 месеца)