1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
6pub struct LocalizedString {
7 pub default: String,
8}
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct Conference {
13 pub abbr: String,
14 pub name: String,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
19pub struct Division {
20 pub abbr: String,
21 pub name: String,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
26pub struct Team {
27 pub name: String,
28 pub common_name: String,
29 pub abbr: String,
30 pub logo: String,
31 pub conference: Conference,
32 pub division: Division,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub franchise_id: Option<i64>,
35}
36
37impl fmt::Display for Team {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{} ({})", self.name, self.abbr)
40 }
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
45pub struct Franchise {
46 pub id: i64,
47 #[serde(rename = "fullName")]
48 pub full_name: String,
49 #[serde(rename = "teamCommonName")]
50 pub team_common_name: Option<String>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct FranchisesResponse {
56 pub data: Vec<Franchise>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct Roster {
63 #[serde(default)]
64 pub forwards: Vec<RosterPlayer>,
65 #[serde(default)]
66 pub defensemen: Vec<RosterPlayer>,
67 #[serde(default)]
68 pub goalies: Vec<RosterPlayer>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
73pub struct RosterPlayer {
74 pub id: i64,
75 pub headshot: String,
76 #[serde(rename = "firstName")]
77 pub first_name: LocalizedString,
78 #[serde(rename = "lastName")]
79 pub last_name: LocalizedString,
80 #[serde(rename = "sweaterNumber")]
81 pub sweater_number: i32,
82 #[serde(rename = "positionCode")]
83 pub position_code: String,
84 #[serde(rename = "shootsCatches")]
85 pub shoots_catches: String,
86 #[serde(rename = "heightInInches")]
87 pub height_in_inches: i32,
88 #[serde(rename = "weightInPounds")]
89 pub weight_in_pounds: i32,
90 #[serde(rename = "heightInCentimeters")]
91 pub height_in_centimeters: i32,
92 #[serde(rename = "weightInKilograms")]
93 pub weight_in_kilograms: i32,
94 #[serde(rename = "birthDate")]
95 pub birth_date: String,
96 #[serde(rename = "birthCity")]
97 pub birth_city: LocalizedString,
98 #[serde(rename = "birthCountry")]
99 pub birth_country: String,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 #[serde(rename = "birthStateProvince")]
102 pub birth_state_province: Option<LocalizedString>,
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_team_serialization() {
111 let team = Team {
112 name: "Buffalo Sabres".to_string(),
113 common_name: "Sabres".to_string(),
114 abbr: "BUF".to_string(),
115 logo: "https://assets.nhle.com/logos/nhl/svg/BUF_light.svg".to_string(),
116 conference: Conference {
117 abbr: "E".to_string(),
118 name: "Eastern".to_string(),
119 },
120 division: Division {
121 abbr: "ATL".to_string(),
122 name: "Atlantic".to_string(),
123 },
124 franchise_id: Some(19),
125 };
126
127 let json = serde_json::to_string(&team).unwrap();
128 let deserialized: Team = serde_json::from_str(&json).unwrap();
129
130 assert_eq!(deserialized.name, "Buffalo Sabres");
131 assert_eq!(deserialized.abbr, "BUF");
132 assert_eq!(deserialized.franchise_id, Some(19));
133 }
134
135 #[test]
136 fn test_franchise_response_deserialization() {
137 let json = r#"{
138 "data": [
139 {
140 "id": 19,
141 "fullName": "Buffalo Sabres",
142 "teamCommonName": "Sabres"
143 }
144 ]
145 }"#;
146
147 let response: FranchisesResponse = serde_json::from_str(json).unwrap();
148 assert_eq!(response.data.len(), 1);
149 assert_eq!(response.data[0].id, 19);
150 assert_eq!(response.data[0].full_name, "Buffalo Sabres");
151 }
152
153 #[test]
154 fn test_team_display() {
155 let team = Team {
156 name: "Buffalo Sabres".to_string(),
157 common_name: "Sabres".to_string(),
158 abbr: "BUF".to_string(),
159 logo: "https://assets.nhle.com/logos/nhl/svg/BUF_light.svg".to_string(),
160 conference: Conference {
161 abbr: "E".to_string(),
162 name: "Eastern".to_string(),
163 },
164 division: Division {
165 abbr: "ATL".to_string(),
166 name: "Atlantic".to_string(),
167 },
168 franchise_id: Some(19),
169 };
170
171 assert_eq!(team.to_string(), "Buffalo Sabres (BUF)");
172 }
173}