toasty_core/schema/name.rs
1use heck::{ToSnakeCase, ToUpperCamelCase};
2
3/// A multi-part identifier that can be rendered in snake case or upper camel case.
4///
5/// # Examples
6///
7/// ```
8/// use toasty_core::schema::Name;
9///
10/// let name = Name::new("UserProfile");
11/// assert_eq!(name.snake_case(), "user_profile");
12/// assert_eq!(name.upper_camel_case(), "UserProfile");
13/// ```
14#[derive(Debug, Clone, Eq, PartialEq, Hash)]
15pub struct Name {
16 /// The individual lowercase word parts of this name.
17 pub parts: Vec<String>,
18}
19
20impl Name {
21 /// Creates a new `Name` by splitting `src` into word parts.
22 ///
23 /// The input is first converted to snake_case, then split on underscores.
24 ///
25 /// # Examples
26 ///
27 /// ```
28 /// use toasty_core::schema::Name;
29 ///
30 /// let name = Name::new("myField");
31 /// assert_eq!(name.parts, vec!["my", "field"]);
32 /// ```
33 pub fn new(src: &str) -> Self {
34 // TODO: make better
35 let snake = src.to_snake_case();
36 let parts = snake.split('_').map(String::from).collect();
37 Self { parts }
38 }
39
40 /// Returns this name in `UpperCamelCase` (PascalCase).
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use toasty_core::schema::Name;
46 ///
47 /// assert_eq!(Name::new("user_id").upper_camel_case(), "UserId");
48 /// ```
49 pub fn upper_camel_case(&self) -> String {
50 self.snake_case().to_upper_camel_case()
51 }
52
53 /// Returns this name in `snake_case`.
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use toasty_core::schema::Name;
59 ///
60 /// assert_eq!(Name::new("UserProfile").snake_case(), "user_profile");
61 /// ```
62 pub fn snake_case(&self) -> String {
63 self.parts.join("_")
64 }
65}
66
67impl core::fmt::Display for Name {
68 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69 f.write_str(&self.upper_camel_case())
70 }
71}