Форматиране на импорти
- Краен срок:
- 03.12.2024 18:00
- Точки:
- 20
Срокът за предаване на решения е отминал
Import-ите в Rust могат да се напишат по няколко различни начина, в зависимост от продпочитанията на програмиста:
// по един импорт на ред
use std::iter;
use std::iter::once;
use std::iter::repeat;
// групирани по модули
use std::collections::hash_map::{Entry, HashMap};
use std::vec::{IntoIter, Vec};
// групирани в едно `use` твърдение
use std::sync::{
Arc,
mpsc::{
Sender,
Receiver,
},
};
Целта на това задание е да напишете програма, която форматира списък от импорти в два различни стила.
Програмата трябва да съдържа следното (можете да добавяте произволни derive
-ове и методи на Import
и Order
, ако са ви необходими):
pub struct Import<'a>(pub &'a [&'a str]);
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
todo!()
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
todo!()
}
Импортите ще ви се подават предварително разпарсени и разделени на части. Например std::string::String
ще се подаде като Import(&["std", "string", "String"])
.
Всеки Import
ще бъде валиден и ще съдържа абсолютен път до някакъв item, т.е. задължително ще започва с име на външен пакет (като "std") или с ключовата дума "crate". Няма да има импорти, които завършват със "self".
format_flat
Функцията връща импортите форматирани по един на ред. Всеки ред е един елемент от резултата. Параметърът order
определя как трябва да са подредени импортите. Ако е Original
, трябва се върнат в оригиналния им ред. Ако е Sorted
трябва да се върнат сортирани лексикографски. И в двата случая дубликатите трябва да се премахнат.
Резултатът трябва да изглежда така:
vec![
String::from("my_crate::a"),
String::from("my_crate::b::B1"),
String::from("my_crate::b::B2"),
]
format_nested
Функцията връща импортите групирани в едно use
твърдение за всеки crate (без ключовата дума use
и символа ;
).
Всеки елемент от резултата трябва да изглежда така:
my_crate::{
a,
b::{
B1,
B2,
},
c,
}
- резултатът е вектор, който съдържа по един елемент за всеки crate сред подадените импорти. Всеки елемент на вектора е многоредов низ, като този, показан по-горе;
- форматирането трябва да отговаря точно на показания пример. Всяко ниво на идентация е по 4 интервала;
-
за всеки модул се отваря ново ниво на вложеност, дори и да има само едно име под този модул:
my_crate::{ a::{ b, }, }
-
ако е подаден импорт за модул (
std::b
), както и импорти за имена под този модул (std::b::B1
), импорта на самия модул трябва да се преобразува да използваself
.self
трябва да се добави най-отгоре във вложената група, преди останалите елементи и не се влияе от параметъраorder
:std::{ b::{ self, B1, } }
-
ако са подадени импорти за няколко различни crate-а, резултатът трябва да съдържа по един низ за всеки crate:
vec![ String::from("std::{\n a,\n}\n"), String::from("foo::{\n b,\n}\n"), ]
дубликатите трябва да се премахнат.
Параметърът order
определя в какъв ред трябва да са подредени импортите.
Ако е Original
, първо трябва да се напишат модулите и item-ите, които се срещат по-рано във входа. Следващи срещания на същия модул трябва да се добавят в същата вложена група:
imports = &[
Import(&["foo", "b", "B2"]),
Import(&["foo", "a", "A1"]),
Import(&["foo", "b", "B1"]),
]
// =>
foo::{
b::{
B2,
B1,
},
a::{
A1,
},
}
Ако order
е Sorted
, импортите трябва да са сортирани в лексикографски ред:
imports = &[
Import(&["foo", "b", "B2"]),
Import(&["foo", "a", "A1"]),
Import(&["foo", "b", "B1"]),
]
// =>
foo::{
a::{
A1,
},
b::{
B1,
B2,
},
}
Подсказки
Следното не е по никакъв начин задължително, но ако се чудите как да подходите към задачата, ето ви един съвет:
- Резултатът от
format_nested
има дървовидна форма, затова ще е най-удобно, ако импортите се запазят в дърво, след което това дърво се обходи. Нещо от рода наstruct Tree { root: Node }; struct Node { value: String, children: Контейнер<Node> }
ще свърши работа. Разбира се, в единия случай децата ни трябват в реда на въвеждане, а в другия - сортирани лексикографски. Има много начини това да се постигне.
Не се притеснявайте да копирате и сортирате данните колкото пъти ви трябва - не оценяваме бързината на решението.
Задължително прочетете (или си припомнете): Указания за предаване на домашни
Погрижете се решението ви да се компилира с базовия тест: