1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::artifact::Artifact;
use crate::client::{Client, JobDependency, JobResponse, JobVariable};
use bytes::Bytes;
use std::sync::Arc;
use tokio::sync::mpsc;
pub struct Variable<'a> {
v: &'a JobVariable,
}
impl<'a> Variable<'a> {
pub fn key(&self) -> &'a str {
&self.v.key
}
pub fn value(&self) -> &'a str {
&self.v.value
}
pub fn masked(&self) -> bool {
self.v.masked
}
pub fn public(&self) -> bool {
self.v.public
}
}
impl std::fmt::Display for Variable<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
if self.v.masked {
write!(f, "<MASKED>")
} else {
write!(f, "{}", self.v.value)
}
}
}
#[derive(Debug)]
pub struct Dependency<'a> {
job: &'a Job,
dependency: &'a JobDependency,
}
impl<'a> Dependency<'a> {
pub fn id(&self) -> u64 {
self.dependency.id
}
pub fn name(&self) -> &str {
&self.dependency.name
}
pub fn artifact_filename(&self) -> Option<&str> {
self.dependency
.artifacts_file
.as_ref()
.map(|a| a.filename.as_str())
}
pub fn artifact_size(&self) -> Option<usize> {
self.dependency.artifacts_file.as_ref().map(|a| a.size)
}
pub async fn download(&self) -> Result<Option<Artifact>, crate::client::Error> {
if self.dependency.artifacts_file.is_some() {
let bytes = self
.job
.client
.download_artifact(self.dependency.id, &self.dependency.token)
.await?;
Ok(Some(Artifact::new(bytes)))
} else {
Ok(None)
}
}
}
#[derive(Debug)]
pub(crate) enum JobRequest {
Trace(Bytes),
}
#[derive(Debug)]
pub struct Job {
data: Arc<JobResponse>,
channel: mpsc::Sender<JobRequest>,
client: Client,
}
impl Job {
pub(crate) fn new(
client: Client,
data: Arc<JobResponse>,
channel: mpsc::Sender<JobRequest>,
) -> Self {
Self {
client,
data,
channel,
}
}
pub fn id(&self) -> u64 {
self.data.id
}
pub async fn trace<D: Into<Bytes>>(&self, data: D) {
let r = JobRequest::Trace(data.into());
self.channel.send(r).await.unwrap();
}
pub fn variable(&self, key: &str) -> Option<Variable> {
self.data.variables.get(key).map(|v| Variable { v })
}
pub fn dependencies(&self) -> impl Iterator<Item = Dependency> {
self.data
.dependencies
.iter()
.map(move |dependency| Dependency {
job: self,
dependency,
})
}
}