Exercise: Builder Type

In this example, we will implement a complex data type that owns all of its data. We will use the “builder pattern” to support building a new value piece-by-piece, using convenience functions.

Fill in the missing pieces.

1. ```
   #[derive(Debug)]
   ```
2. ```
   enum Language {
   ```
3. ```
       Rust,
   ```
4. ```
       Java,
   ```
5. ```
       Perl,
   ```
6. ```
   }
   ```

8. ```
   #[derive(Clone, Debug)]
   ```
9. ```
   struct Dependency {
   ```
10. ```
        name: String,
    ```
11. ```
        version_expression: String,
    ```
12. ```
    }
    ```

14. ```
    /// A representation of a software package.
    ```
15. ```
    #[derive(Debug)]
    ```
16. ```
    struct Package {
    ```
17. ```
        name: String,
    ```
18. ```
        version: String,
    ```
19. ```
        authors: Vec<String>,
    ```
20. ```
        dependencies: Vec<Dependency>,
    ```
21. ```
        language: Option<Language>,
    ```
22. ```
    }
    ```

24. ```
    impl Package {
    ```
25. ```
        /// Return a representation of this package as a dependency, for use in
    ```
26. ```
        /// building other packages.
    ```
27. ```
        fn as_dependency(&self) -> Dependency {
    ```
28. ```
            todo!("1")
    ```
29. ```
        }
    ```
30. ```
    }
    ```

32. ```
    /// A builder for a Package. Use `build()` to create the `Package` itself.
    ```
33. ```
    struct PackageBuilder(Package);
    ```

35. ```
    impl PackageBuilder {
    ```
36. ```
        fn new(name: impl Into<String>) -> Self {
    ```
37. ```
            todo!("2")
    ```
38. ```
        }
    ```

40. ```
        /// Set the package version.
    ```
41. ```
        fn version(mut self, version: impl Into<String>) -> Self {
    ```
42. ```
            self.0.version = version.into();
    ```
43. ```
            self
    ```
44. ```
        }
    ```

46. ```
        /// Set the package authors.
    ```
47. ```
        fn authors(mut self, authors: Vec<String>) -> Self {
    ```
48. ```
            todo!("3")
    ```
49. ```
        }
    ```

51. ```
        /// Add an additional dependency.
    ```
52. ```
        fn dependency(mut self, dependency: Dependency) -> Self {
    ```
53. ```
            todo!("4")
    ```
54. ```
        }
    ```

56. ```
        /// Set the language. If not set, language defaults to None.
    ```
57. ```
        fn language(mut self, language: Language) -> Self {
    ```
58. ```
            todo!("5")
    ```
59. ```
        }
    ```

61. ```
        fn build(self) -> Package {
    ```
62. ```
            self.0
    ```
63. ```
        }
    ```
64. ```
    }
    ```

66. ```
    fn main() {
    ```
67. ```
        let base64 = PackageBuilder::new("base64").version("0.13").build();
    ```
68. ```
        println!("base64: {base64:?}");
    ```
69. ```
        let log =
    ```
70. ```
            PackageBuilder::new("log").version("0.4").language(Language::Rust).build();
    ```
71. ```
        println!("log: {log:?}");
    ```
72. ```
        let serde = PackageBuilder::new("serde")
    ```
73. ```
            .authors(vec!["djmitche".into()])
    ```
74. ```
            .version(String::from("4.0"))
    ```
75. ```
            .dependency(base64.as_dependency())
    ```
76. ```
            .dependency(log.as_dependency())
    ```
77. ```
            .build();
    ```
78. ```
        println!("serde: {serde:?}");
    ```
79. ```
    }
    ```