Упражнение: Тип-построитель
В этом примере мы реализуем сложный тип данных, который владеет всеми своими данными. Мы используем «паттерн строитель» (builder pattern), чтобы поддержать постепенное построение нового значения с помощью удобных функций.
Заполните недостающие части.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#[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 to_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();
dbg!(&base64);
let log =
PackageBuilder::new("log").version("0.4").language(Language::Rust).build();
dbg!(&log);
let serde = PackageBuilder::new("serde")
.authors(vec!["djmitche".into()])
.version(String::from("4.0"))
.dependency(base64.to_dependency())
.dependency(log.to_dependency())
.build();
dbg!(serde);
}