Решение на Форматиране на импорти от Калоян Рибаров
Резултати
- 18 точки от тестове
- 2 бонус точки
- 20 точки общо
- 18 успешни тест(а)
- 2 неуспешни тест(а)
Код
use std::cmp::Ordering;
use std::vec;
use std::collections::HashSet;
#[derive(Debug)]
pub struct Import<'a>(pub &'a [&'a str]);
#[derive(PartialEq)]
pub enum Order {
Original,
Sorted,
}
struct Tree { root: Node }
#[derive(Debug)]
#[derive(Clone)]
struct Node { value: String, children: Vec<Node>, is_imported: bool }
impl Node {
pub fn new(value: String) -> Node {
Node { value, children: vec![], is_imported: false }
}
pub fn new_import(value: String) -> Node {
Node { value, children: vec![], is_imported: true }
}
fn add_elem_helper(&mut self, import: &Import) -> bool {
match import.0 {
&[] => true,
&[x] => {
let opt_node = self.children.iter_mut().find(|child| child.value == x.to_owned());
match opt_node {
Some(node) => {
node.children.insert(0, Node::new_import("self".to_string()));
return true;
}
None => {
self.children.push(Node::new_import(x.to_string()));
true
}
}
},
&[x, ..] => {
let mut children_iter = self.children.iter_mut();
if let Some(node) = children_iter.find(|child| child.value == x) {
if node.is_imported && !node.children.iter().any(|child| child.value == "self".to_string()) {
node.children.insert(0, Node::new_import("self".to_string()));
}
return node.add_elem_helper(&Import(&import.0[1..]));
} else {
self.children.push(Node::new(x.to_owned()));
if let Some(node) = self.children.last_mut() {
node.add_elem_helper(&Import(&import.0[1..]))
} else {
false
}
}
}
}
}
fn print_helper(&self, depth: usize, order: &Order) -> String {
if self.children.is_empty() {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str(",\n");
return str
} else {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str("::{");
str.push_str("\n");
let mut children = self.children.clone();
if *order == Order::Sorted {
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
})
}
let a: String = children.iter().map(|child| child.print_helper(depth + 1, order)).collect();
str.push_str(&a);
for _ in 0..depth {
str.push_str(" ");
}
str.push_str("},\n");
str
}
}
pub fn print(&self, depth: usize, order: &Order) -> String {
self.print_helper(depth, order)
}
pub fn add_elem(&mut self, import: &Import) -> bool {
self.add_elem_helper(import)
}
}
impl Tree {
fn new(value: String) -> Tree {
Tree { root: Node { value, children: vec![], is_imported: false } }
}
fn add_elem(&mut self, import: &Import) -> bool {
self.root.add_elem(import)
}
fn print(&self, order: Order) -> Vec<String> {
let arranged_children = match order {
Order::Original => self.root.children.clone(),
Order::Sorted => {
let mut children = self.root.children.clone();
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
});
children
}
};
arranged_children.iter().map(|node|
{
let mut temporary_string = node.print(0, &order);
let ans = temporary_string.as_mut();//.map(|x| x.replace_range(x.len()-2..x.len()-1, ""))
let mut f = ans[..ans.len() - 2].to_string();
f.push_str("\n");
f
}).collect()
}
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut unique_strings: HashSet<String> = HashSet::new();
let mut imports = imports.iter()
.filter_map(|Import(x)| {
let joined = x.join("::");
if unique_strings.insert(joined.clone()) {
Some(joined)
} else {
None
}
})
.collect();
match order {
Order::Original => imports,
Order::Sorted => {
imports.sort();
imports
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new(String::from(""));
for import in imports {
tree.add_elem(import);
}
tree.print(order)
}
#[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".to_string(),
"my_crate::b::B1".to_string(),
"my_crate::b::B2".to_string(),
"my_crate::c".to_string(),
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self() {
let imports = &[Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" self,\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self_before() {
let imports = &[
Import(&["my_crate", "b"]),
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" self,\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self_top_level() {
let imports = &[
Import(&["my_crate"]),
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" self,\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_correctly_prints_elements_chronologically() {
let imports = &[
Import(&["my_crate", "b", "C"]),
Import(&["my_crate", "a", "B"]),
Import(&["my_crate", "b", "A"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_correctly_prints_elements_multiple_crates() {
let imports = &[
Import(&["my_crate", "b", "C"]),
Import(&["my_crate", "a", "B"]),
Import(&["my_crate", "b", "A"]),
Import(&["my_crate", "c"]),
Import(&["my-crate", "b", "C"]),
Import(&["my-crate", "a", "B"]),
Import(&["my-crate", "b", "A"]),
Import(&["my-crate", "c"])];
let result = format_nested(imports, Order::Original);
assert_eq!(result.len(), 2);
assert_eq!(
result,
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string(),
concat!(
"my-crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_does_not_panic_if_only_one_level_import_is_provied() {
let imports = &[
Import(&["my_crate", "b", "C"])];
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" },\n",
"}\n",
).to_string()
]
)
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20241203-1739405-ahfc06/solution) Finished test [unoptimized + debuginfo] target(s) in 2.02s 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 ... ok test solution_test::test_nested_original ... ok test solution_test::test_nested_original_2 ... ok test solution_test::test_nested_original_duplicates ... FAILED 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 ... FAILED test solution_test::test_nested_sorted_multi_crate ... ok test solution_test::test_nested_sorted_self ... ok failures: ---- solution_test::test_nested_original_duplicates stdout ---- thread 'solution_test::test_nested_original_duplicates' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n c::{\n self,\n },\n b::{\n B2::{\n self,\n },\n B1,\n },\n a,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n B2,\n B1,\n },\n a,\n}\n"]`', tests/solution_test.rs:283:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- solution_test::test_nested_sorted_duplicates stdout ---- thread 'solution_test::test_nested_sorted_duplicates' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2::{\n self,\n },\n },\n c::{\n self,\n },\n}\n"]`, right: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`', tests/solution_test.rs:309:5 failures: solution_test::test_nested_original_duplicates solution_test::test_nested_sorted_duplicates test result: FAILED. 18 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass `--test solution_test`
История (5 версии и 0 коментара)
Калоян качи решение на 03.12.2024 16:49 (преди 9 месеца)
use std::cmp::Ordering;
use std::{vec};
use std::collections::{HashSet};
#[derive(Debug)]
pub struct Import<'a>(pub &'a [&'a str]);
#[derive(PartialEq, PartialOrd)]
pub enum Order {
Original,
Sorted,
}
struct Tree { root: Node }
#[derive(Debug)]
#[derive(Clone)]
struct Node { value: String, children: Vec<Node>, is_imported: bool }
impl Node {
pub fn new(value: String) -> Node {
Node { value, children: vec![], is_imported: false }
}
pub fn new_import(value: String) -> Node {
Node { value, children: vec![], is_imported: true }
}
fn add_elem_helper(&mut self, import: &Import) -> bool {
match import.0 {
&[] => true,
&[x] => {
let opt_node = self.children.iter_mut().find(|child| child.value == x.to_owned());
match opt_node {
Some(node) => {
node.children.insert(0, Node::new_import("self".to_string()));
return true;
}
None => {
self.children.push(Node::new_import(x.to_string()));
true
}
}
},
&[x, ..] => {
let mut children_iter = self.children.iter_mut();
if let Some(node) = children_iter.find(|child| child.value == x) {
if node.is_imported && !node.children.iter().any(|child| child.value == "self".to_string()) {
node.children.insert(0, Node::new_import("self".to_string()));
}
return node.add_elem_helper(&Import(&import.0[1..]));
} else {
self.children.push(Node::new(x.to_owned()));
if let Some(node) = self.children.last_mut() {
node.add_elem_helper(&Import(&import.0[1..]))
} else {
false
}
}
}
}
}
fn print_helper(&self, depth: usize, order: &Order) -> String {
if self.children.is_empty() {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str(",\n");
return str
} else {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str("::{");
str.push_str("\n");
let mut children = self.children.clone();
if *order == Order::Sorted {
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
})
}
let a: String = children.iter().map(|child| child.print_helper(depth + 1, order)).collect();
str.push_str(&a);
for _ in 0..depth {
str.push_str(" ");
}
str.push_str("},\n");
str
}
}
pub fn print(&self, depth: usize, order: &Order) -> String {
self.print_helper(depth, order)
}
pub fn add_elem(&mut self, import: &Import) -> bool {
self.add_elem_helper(import)
}
}
impl Tree {
fn new(value: String) -> Tree {
Tree { root: Node { value, children: vec![], is_imported: false } }
}
fn add_elem(&mut self, import: &Import) -> bool {
self.root.add_elem(import)
}
fn print(&self, order: Order) -> Vec<String> {
- self.root.children.iter().map(|node|
+ let arranged_children = match order {
+ Order::Original => self.root.children.clone(),
+
+ Order::Sorted => {
+ let mut children = self.root.children.clone();
+
+ children.sort_by(|first_node, second_node| {
+ if first_node.value == "self" {
+ return Ordering::Less;
+ } else if second_node.value == "self" {
+ return Ordering::Greater;
+ }
+
+ return first_node.value.cmp(&second_node.value);
+ });
+ children
+ }
+ };
+
+ arranged_children.iter().map(|node|
{
let mut temporary_string = node.print(0, &order);
let ans = temporary_string.as_mut();//.map(|x| x.replace_range(x.len()-2..x.len()-1, ""))
let mut f = ans[..ans.len() - 2].to_string();
f.push_str("\n");
f
}).collect()
}
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut unique_strings: HashSet<String> = HashSet::new();
let mut imports = imports.iter()
.filter_map(|Import(x)| {
let joined = x.join("::");
if unique_strings.insert(joined.clone()) {
Some(joined)
} else {
None
}
})
.collect();
match order {
Order::Original => imports,
Order::Sorted => {
imports.sort();
imports
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new(String::from(""));
for import in imports {
tree.add_elem(import);
}
tree.print(order)
}
Калоян качи решение на 03.12.2024 17:08 (преди 9 месеца)
use std::cmp::Ordering;
use std::{vec};
use std::collections::{HashSet};
#[derive(Debug)]
pub struct Import<'a>(pub &'a [&'a str]);
#[derive(PartialEq, PartialOrd)]
pub enum Order {
Original,
Sorted,
}
struct Tree { root: Node }
#[derive(Debug)]
#[derive(Clone)]
struct Node { value: String, children: Vec<Node>, is_imported: bool }
impl Node {
pub fn new(value: String) -> Node {
Node { value, children: vec![], is_imported: false }
}
pub fn new_import(value: String) -> Node {
Node { value, children: vec![], is_imported: true }
}
fn add_elem_helper(&mut self, import: &Import) -> bool {
match import.0 {
&[] => true,
&[x] => {
let opt_node = self.children.iter_mut().find(|child| child.value == x.to_owned());
match opt_node {
Some(node) => {
node.children.insert(0, Node::new_import("self".to_string()));
return true;
}
None => {
self.children.push(Node::new_import(x.to_string()));
true
}
}
},
&[x, ..] => {
let mut children_iter = self.children.iter_mut();
if let Some(node) = children_iter.find(|child| child.value == x) {
if node.is_imported && !node.children.iter().any(|child| child.value == "self".to_string()) {
node.children.insert(0, Node::new_import("self".to_string()));
}
return node.add_elem_helper(&Import(&import.0[1..]));
} else {
self.children.push(Node::new(x.to_owned()));
if let Some(node) = self.children.last_mut() {
node.add_elem_helper(&Import(&import.0[1..]))
} else {
false
}
}
}
}
}
fn print_helper(&self, depth: usize, order: &Order) -> String {
if self.children.is_empty() {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str(",\n");
return str
} else {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str("::{");
str.push_str("\n");
let mut children = self.children.clone();
if *order == Order::Sorted {
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
})
}
let a: String = children.iter().map(|child| child.print_helper(depth + 1, order)).collect();
str.push_str(&a);
for _ in 0..depth {
str.push_str(" ");
}
str.push_str("},\n");
str
}
}
pub fn print(&self, depth: usize, order: &Order) -> String {
self.print_helper(depth, order)
}
pub fn add_elem(&mut self, import: &Import) -> bool {
self.add_elem_helper(import)
}
}
impl Tree {
fn new(value: String) -> Tree {
Tree { root: Node { value, children: vec![], is_imported: false } }
}
fn add_elem(&mut self, import: &Import) -> bool {
self.root.add_elem(import)
}
fn print(&self, order: Order) -> Vec<String> {
let arranged_children = match order {
Order::Original => self.root.children.clone(),
Order::Sorted => {
let mut children = self.root.children.clone();
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
});
children
}
};
-
+
arranged_children.iter().map(|node|
{
let mut temporary_string = node.print(0, &order);
let ans = temporary_string.as_mut();//.map(|x| x.replace_range(x.len()-2..x.len()-1, ""))
let mut f = ans[..ans.len() - 2].to_string();
f.push_str("\n");
f
}).collect()
}
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut unique_strings: HashSet<String> = HashSet::new();
let mut imports = imports.iter()
.filter_map(|Import(x)| {
let joined = x.join("::");
if unique_strings.insert(joined.clone()) {
Some(joined)
} else {
None
}
})
.collect();
match order {
Order::Original => imports,
Order::Sorted => {
imports.sort();
imports
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new(String::from(""));
for import in imports {
tree.add_elem(import);
}
tree.print(order)
}
Калоян качи решение на 03.12.2024 17:22 (преди 9 месеца)
use std::cmp::Ordering;
use std::{vec};
use std::collections::{HashSet};
#[derive(Debug)]
pub struct Import<'a>(pub &'a [&'a str]);
#[derive(PartialEq, PartialOrd)]
pub enum Order {
Original,
Sorted,
}
struct Tree { root: Node }
#[derive(Debug)]
#[derive(Clone)]
struct Node { value: String, children: Vec<Node>, is_imported: bool }
impl Node {
pub fn new(value: String) -> Node {
Node { value, children: vec![], is_imported: false }
}
pub fn new_import(value: String) -> Node {
Node { value, children: vec![], is_imported: true }
}
fn add_elem_helper(&mut self, import: &Import) -> bool {
match import.0 {
&[] => true,
&[x] => {
let opt_node = self.children.iter_mut().find(|child| child.value == x.to_owned());
match opt_node {
Some(node) => {
node.children.insert(0, Node::new_import("self".to_string()));
return true;
}
None => {
self.children.push(Node::new_import(x.to_string()));
true
}
}
},
&[x, ..] => {
let mut children_iter = self.children.iter_mut();
if let Some(node) = children_iter.find(|child| child.value == x) {
if node.is_imported && !node.children.iter().any(|child| child.value == "self".to_string()) {
node.children.insert(0, Node::new_import("self".to_string()));
}
return node.add_elem_helper(&Import(&import.0[1..]));
} else {
self.children.push(Node::new(x.to_owned()));
if let Some(node) = self.children.last_mut() {
node.add_elem_helper(&Import(&import.0[1..]))
} else {
false
}
}
}
}
}
fn print_helper(&self, depth: usize, order: &Order) -> String {
if self.children.is_empty() {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str(",\n");
return str
} else {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str("::{");
str.push_str("\n");
let mut children = self.children.clone();
if *order == Order::Sorted {
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
})
}
let a: String = children.iter().map(|child| child.print_helper(depth + 1, order)).collect();
str.push_str(&a);
for _ in 0..depth {
str.push_str(" ");
}
str.push_str("},\n");
str
}
}
pub fn print(&self, depth: usize, order: &Order) -> String {
self.print_helper(depth, order)
}
pub fn add_elem(&mut self, import: &Import) -> bool {
self.add_elem_helper(import)
}
}
impl Tree {
fn new(value: String) -> Tree {
Tree { root: Node { value, children: vec![], is_imported: false } }
}
fn add_elem(&mut self, import: &Import) -> bool {
self.root.add_elem(import)
}
fn print(&self, order: Order) -> Vec<String> {
let arranged_children = match order {
Order::Original => self.root.children.clone(),
Order::Sorted => {
let mut children = self.root.children.clone();
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
});
children
}
};
arranged_children.iter().map(|node|
{
let mut temporary_string = node.print(0, &order);
let ans = temporary_string.as_mut();//.map(|x| x.replace_range(x.len()-2..x.len()-1, ""))
let mut f = ans[..ans.len() - 2].to_string();
f.push_str("\n");
f
}).collect()
}
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut unique_strings: HashSet<String> = HashSet::new();
let mut imports = imports.iter()
.filter_map(|Import(x)| {
let joined = x.join("::");
if unique_strings.insert(joined.clone()) {
Some(joined)
} else {
None
}
})
.collect();
match order {
Order::Original => imports,
Order::Sorted => {
imports.sort();
imports
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new(String::from(""));
for import in imports {
tree.add_elem(import);
}
tree.print(order)
}
+
+#[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".to_string(),
+ "my_crate::b::B1".to_string(),
+ "my_crate::b::B2".to_string(),
+ "my_crate::c".to_string(),
+ ]
+ );
+
+ assert_eq!(
+ format_nested(imports, Order::Sorted),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " a,\n",
+ " b::{\n",
+ " B1,\n",
+ " B2,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_adds_self() {
+ let imports = &[Import(&["my_crate", "a"]),
+ Import(&["my_crate", "b", "B1"]),
+ Import(&["my_crate", "b", "B2"]),
+ Import(&["my_crate", "b"]),
+ Import(&["my_crate", "c"])];
+
+ assert_eq!(
+ format_nested(imports, Order::Sorted),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " a,\n",
+ " b::{\n",
+ " self,\n",
+ " B1,\n",
+ " B2,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_adds_self_before() {
+ let imports = &[
+ Import(&["my_crate", "b"]),
+ Import(&["my_crate", "a"]),
+ Import(&["my_crate", "b", "B1"]),
+ Import(&["my_crate", "b", "B2"]),
+
+ Import(&["my_crate", "c"])];
+
+ assert_eq!(
+ format_nested(imports, Order::Sorted),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " a,\n",
+ " b::{\n",
+ " self,\n",
+ " B1,\n",
+ " B2,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_adds_self_top_level() {
+ let imports = &[
+ Import(&["my_crate"]),
+ Import(&["my_crate", "a"]),
+ Import(&["my_crate", "b", "B1"]),
+ Import(&["my_crate", "b", "B2"]),
+
+ Import(&["my_crate", "c"])];
+
+ assert_eq!(
+ format_nested(imports, Order::Sorted),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " self,\n",
+ " a,\n",
+ " b::{\n",
+ " B1,\n",
+ " B2,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_correctly_prints_elements_chronologically() {
+ let imports = &[
+ Import(&["my_crate", "b", "C"]),
+ Import(&["my_crate", "a", "B"]),
+ Import(&["my_crate", "b", "A"]),
+
+ Import(&["my_crate", "c"])];
+
+ assert_eq!(
+ format_nested(imports, Order::Original),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " b::{\n",
+ " C,\n",
+ " A,\n",
+ " },\n",
+ " a::{\n",
+ " B,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_correctly_prints_elements_multiple_crates() {
+ let imports = &[
+ Import(&["my_crate", "b", "C"]),
+ Import(&["my_crate", "a", "B"]),
+ Import(&["my_crate", "b", "A"]),
+
+ Import(&["my_crate", "c"]),
+ Import(&["my-crate", "b", "C"]),
+ Import(&["my-crate", "a", "B"]),
+ Import(&["my-crate", "b", "A"]),
+
+ Import(&["my-crate", "c"])];
+
+
+ let result = format_nested(imports, Order::Original);
+ assert_eq!(result.len(), 2);
+
+ assert_eq!(
+ result,
+ &[
+ concat!(
+ "my_crate::{\n",
+ " b::{\n",
+ " C,\n",
+ " A,\n",
+ " },\n",
+ " a::{\n",
+ " B,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string(),
+ concat!(
+ "my-crate::{\n",
+ " b::{\n",
+ " C,\n",
+ " A,\n",
+ " },\n",
+ " a::{\n",
+ " B,\n",
+ " },\n",
+ " c,\n",
+ "}\n",
+ ).to_string()
+ ]
+ );
+}
+
+#[test]
+fn test_does_not_panic_if_only_one_level_import_is_provied() {
+ let imports = &[
+ Import(&["my_crate", "b", "C"])];
+
+ assert_eq!(
+ format_nested(imports, Order::Original),
+ &[
+ concat!(
+ "my_crate::{\n",
+ " b::{\n",
+ " C,\n",
+ " },\n",
+ "}\n",
+ ).to_string()
+ ]
+ )
+}
+
Калоян качи решение на 03.12.2024 17:31 (преди 9 месеца)
use std::cmp::Ordering;
-use std::{vec};
-use std::collections::{HashSet};
+use std::vec;
+use std::collections::HashSet;
#[derive(Debug)]
pub struct Import<'a>(pub &'a [&'a str]);
-#[derive(PartialEq, PartialOrd)]
+#[derive(PartialEq)]
pub enum Order {
Original,
Sorted,
}
struct Tree { root: Node }
#[derive(Debug)]
#[derive(Clone)]
struct Node { value: String, children: Vec<Node>, is_imported: bool }
impl Node {
pub fn new(value: String) -> Node {
Node { value, children: vec![], is_imported: false }
}
pub fn new_import(value: String) -> Node {
Node { value, children: vec![], is_imported: true }
}
fn add_elem_helper(&mut self, import: &Import) -> bool {
match import.0 {
&[] => true,
&[x] => {
let opt_node = self.children.iter_mut().find(|child| child.value == x.to_owned());
match opt_node {
Some(node) => {
node.children.insert(0, Node::new_import("self".to_string()));
return true;
}
None => {
self.children.push(Node::new_import(x.to_string()));
true
}
}
},
&[x, ..] => {
let mut children_iter = self.children.iter_mut();
if let Some(node) = children_iter.find(|child| child.value == x) {
if node.is_imported && !node.children.iter().any(|child| child.value == "self".to_string()) {
node.children.insert(0, Node::new_import("self".to_string()));
}
return node.add_elem_helper(&Import(&import.0[1..]));
} else {
self.children.push(Node::new(x.to_owned()));
if let Some(node) = self.children.last_mut() {
node.add_elem_helper(&Import(&import.0[1..]))
} else {
false
}
}
}
}
}
fn print_helper(&self, depth: usize, order: &Order) -> String {
if self.children.is_empty() {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str(",\n");
return str
} else {
let mut str = String::from("");
for _ in 0..depth {
str.push_str(" ");
}
str.push_str(&self.value);
str.push_str("::{");
str.push_str("\n");
let mut children = self.children.clone();
if *order == Order::Sorted {
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
})
}
let a: String = children.iter().map(|child| child.print_helper(depth + 1, order)).collect();
str.push_str(&a);
for _ in 0..depth {
str.push_str(" ");
}
str.push_str("},\n");
str
}
}
pub fn print(&self, depth: usize, order: &Order) -> String {
self.print_helper(depth, order)
}
pub fn add_elem(&mut self, import: &Import) -> bool {
self.add_elem_helper(import)
}
}
impl Tree {
fn new(value: String) -> Tree {
Tree { root: Node { value, children: vec![], is_imported: false } }
}
fn add_elem(&mut self, import: &Import) -> bool {
self.root.add_elem(import)
}
fn print(&self, order: Order) -> Vec<String> {
let arranged_children = match order {
Order::Original => self.root.children.clone(),
Order::Sorted => {
let mut children = self.root.children.clone();
children.sort_by(|first_node, second_node| {
if first_node.value == "self" {
return Ordering::Less;
} else if second_node.value == "self" {
return Ordering::Greater;
}
return first_node.value.cmp(&second_node.value);
});
children
}
};
arranged_children.iter().map(|node|
{
let mut temporary_string = node.print(0, &order);
let ans = temporary_string.as_mut();//.map(|x| x.replace_range(x.len()-2..x.len()-1, ""))
let mut f = ans[..ans.len() - 2].to_string();
f.push_str("\n");
f
}).collect()
}
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut unique_strings: HashSet<String> = HashSet::new();
let mut imports = imports.iter()
.filter_map(|Import(x)| {
let joined = x.join("::");
if unique_strings.insert(joined.clone()) {
Some(joined)
} else {
None
}
})
.collect();
match order {
Order::Original => imports,
Order::Sorted => {
imports.sort();
imports
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new(String::from(""));
for import in imports {
tree.add_elem(import);
}
tree.print(order)
}
#[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".to_string(),
"my_crate::b::B1".to_string(),
"my_crate::b::B2".to_string(),
"my_crate::c".to_string(),
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self() {
let imports = &[Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" self,\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self_before() {
let imports = &[
Import(&["my_crate", "b"]),
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" self,\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_adds_self_top_level() {
let imports = &[
Import(&["my_crate"]),
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" self,\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_correctly_prints_elements_chronologically() {
let imports = &[
Import(&["my_crate", "b", "C"]),
Import(&["my_crate", "a", "B"]),
Import(&["my_crate", "b", "A"]),
Import(&["my_crate", "c"])];
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_correctly_prints_elements_multiple_crates() {
let imports = &[
Import(&["my_crate", "b", "C"]),
Import(&["my_crate", "a", "B"]),
Import(&["my_crate", "b", "A"]),
Import(&["my_crate", "c"]),
Import(&["my-crate", "b", "C"]),
Import(&["my-crate", "a", "B"]),
Import(&["my-crate", "b", "A"]),
Import(&["my-crate", "c"])];
let result = format_nested(imports, Order::Original);
assert_eq!(result.len(), 2);
assert_eq!(
result,
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string(),
concat!(
"my-crate::{\n",
" b::{\n",
" C,\n",
" A,\n",
" },\n",
" a::{\n",
" B,\n",
" },\n",
" c,\n",
"}\n",
).to_string()
]
);
}
#[test]
fn test_does_not_panic_if_only_one_level_import_is_provied() {
let imports = &[
Import(&["my_crate", "b", "C"])];
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" b::{\n",
" C,\n",
" },\n",
"}\n",
).to_string()
]
)
}