Вправа: Тип будівельника
У цьому прикладі ми реалізуємо складний тип даних, який володіє всіма своїми даними. Ми використаємо патерн "конструктор" для підтримки побудови нового значення по частинах за допомогою зручних функцій.
Заповніть пропущені частини.
#[derive(Debug)] enum Language { Rust, Java, Perl, } #[derive(Clone, Debug)] struct Dependency { name: String, version_expression: String, } /// Представлення програмного пакету. #[derive(Debug)] struct Package { name: String, version: String, authors: Vec<String>, dependencies: Vec<Dependency>, language: Option<Language>, } impl Package { /// Повертає представлення цього пакунка у вигляді залежності для використання у /// збірці інших пакетів. fn as_dependency(&self) -> Dependency { todo!("1") } } /// Конструктор для Package. Використовуйте `build()` для створення самого `Package`. struct PackageBuilder(Package); impl PackageBuilder { fn new(name: impl Into<String>) -> Self { todo!("2") } /// Задає версію пакета. fn version(mut self, version: impl Into<String>) -> Self { self.0.version = version.into(); self } /// Задає автора пакета. fn authors(mut self, authors: Vec<String>) -> Self { todo!("3") } /// Додає додаткову залежність. fn dependency(mut self, dependency: Dependency) -> Self { todo!("4") } /// Задає мову. Якщо не вказано, за замовчуванням буде встановлено значення None. fn language(mut self, language: Language) -> Self { todo!("5") } fn build(self) -> Package { self.0 } } fn main() { let base64 = PackageBuilder::new("base64").version("0.13").build(); println!("base64: {base64:?}"); let log = PackageBuilder::new("log").version("0.4").language(Language::Rust).build(); println!("log: {log:?}"); let serde = PackageBuilder::new("serde") .authors(vec!["djmitche".into()]) .version(String::from("4.0")) .dependency(base64.as_dependency()) .dependency(log.as_dependency()) .build(); println!("serde: {serde:?}"); }