1use serde::{Deserialize, Serialize};
11
12use crate::error::GithubError;
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
16#[serde(transparent)]
17pub struct OrgSlug(String);
18
19impl OrgSlug {
20 pub fn parse(raw: impl AsRef<str>) -> Result<Self, GithubError> {
21 let raw = raw.as_ref().trim();
22 if raw.is_empty() {
23 return Err(GithubError::InvalidIdentifier("empty".into()));
24 }
25 Ok(Self(raw.to_string()))
26 }
27
28 #[must_use]
29 pub fn as_str(&self) -> &str {
30 &self.0
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39pub struct Organization {
40 pub login: OrgSlug,
41 pub html_url: String,
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn identifier_rejects_empty() {
50 assert!(OrgSlug::parse("").is_err());
53 assert!(OrgSlug::parse(" ").is_err());
54 }
55
56 #[test]
57 fn entity_serde_round_trips() {
58 let e = Organization {
61 login: OrgSlug::parse("STUB-001").unwrap(),
62 html_url: "Stub Entity".into(),
63 };
64 let json = serde_json::to_string(&e).unwrap();
65 let back: Organization = serde_json::from_str(&json).unwrap();
66 assert_eq!(back, e);
67 }
68}