1use chrono::{DateTime, Utc};
2use git2::Signature;
3use std::str::FromStr;
4
5use crate::Error;
6
7pub struct Actor {
9 inner: Signature<'static>,
10}
11
12impl FromStr for Actor {
13 type Err = Error;
14
15 fn from_str(s: &str) -> Result<Self, Self::Err> {
23 let name = s.split('<').next().unwrap().trim();
24 let email = s.split('<').nth(1).unwrap().trim_end_matches('>');
25 let time = git2::Time::new(0, 0);
28
29 let sig = Signature::new(name, email, &time).map_err(Error::Git)?;
30 Ok(Self::new(sig))
31 }
32}
33
34impl Actor {
35 pub fn new(signature: Signature<'_>) -> Self {
37 Self {
38 inner: signature.to_owned(),
39 }
40 }
41
42 pub fn name(&self) -> Option<String> {
44 self.inner.name().map(|s| s.to_string())
45 }
46
47 pub fn email(&self) -> Option<String> {
49 self.inner.email().map(|s| s.to_string())
50 }
51
52 pub fn timestamp(&self) -> Option<DateTime<Utc>> {
54 DateTime::from_timestamp_secs(self.inner.when().seconds())
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_actor() {
64 let sig = Signature::new(
65 "test",
66 "test@example.com",
67 &git2::Time::new(1_600_000_000, 0),
68 )
69 .unwrap();
70
71 let actor = Actor::new(sig);
72
73 assert_eq!(actor.name(), Some("test".to_string()));
74 assert_eq!(actor.email(), Some("test@example.com".to_string()));
75 assert_eq!(actor.timestamp().unwrap().timestamp(), 1_600_000_000);
76 }
77}