Skip to main content

jira_core/model/
worklog.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Worklog {
6    pub id: String,
7    pub issue_key: String,
8    pub author: Option<String>,
9    pub time_spent: String,
10    pub time_spent_seconds: u64,
11    pub started: String,
12    pub comment: Option<String>,
13    pub created: String,
14    pub updated: String,
15}
16
17impl Worklog {
18    pub fn from_value(v: &Value, issue_key: &str) -> Option<Self> {
19        Some(Worklog {
20            id: v.get("id")?.as_str()?.to_string(),
21            issue_key: issue_key.to_string(),
22            author: v
23                .get("author")
24                .and_then(|a| a.get("displayName").or_else(|| a.get("emailAddress")))
25                .and_then(|n| n.as_str())
26                .map(|s| s.to_string()),
27            time_spent: v
28                .get("timeSpent")
29                .and_then(|t| t.as_str())
30                .unwrap_or("")
31                .to_string(),
32            time_spent_seconds: v
33                .get("timeSpentSeconds")
34                .and_then(|t| t.as_u64())
35                .unwrap_or(0),
36            started: v
37                .get("started")
38                .and_then(|t| t.as_str())
39                .unwrap_or("")
40                .to_string(),
41            comment: v
42                .get("comment")
43                .and_then(|c| {
44                    // ADF comment — extract plain text
45                    c.get("content")
46                        .and_then(|arr| arr.as_array())
47                        .and_then(|nodes| nodes.first())
48                        .and_then(|node| node.get("content"))
49                        .and_then(|arr| arr.as_array())
50                        .and_then(|nodes| nodes.first())
51                        .and_then(|node| node.get("text"))
52                        .and_then(|t| t.as_str())
53                        .map(|s| s.to_string())
54                })
55                .or_else(|| {
56                    // Fallback: plain string comment
57                    v.get("comment")
58                        .and_then(|c| c.as_str())
59                        .map(|s| s.to_string())
60                }),
61            created: v
62                .get("created")
63                .and_then(|t| t.as_str())
64                .unwrap_or("")
65                .to_string(),
66            updated: v
67                .get("updated")
68                .and_then(|t| t.as_str())
69                .unwrap_or("")
70                .to_string(),
71        })
72    }
73}