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
126
127
128
129
|
use crate::prelude::*;
use serde::Deserialize as _;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum Env {
V0(V0),
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct V0 {
pipeline: Option<String>,
idx: usize,
#[serde(
serialize_with = "serialize_status",
deserialize_with = "deserialize_status"
)]
latest_status: async_std::process::ExitStatus,
pwd: std::path::PathBuf,
}
impl Env {
pub fn new() -> Self {
Self::V0(V0 {
pipeline: None,
idx: 0,
latest_status: std::process::ExitStatus::from_raw(0),
pwd: std::env::current_dir().unwrap(),
})
}
pub fn pipeline(&self) -> Option<&str> {
match self {
Self::V0(env) => env.pipeline.as_deref(),
}
}
pub fn set_pipeline(&mut self, pipeline: String) {
match self {
Self::V0(env) => {
env.pipeline = Some(pipeline);
}
}
}
pub fn idx(&self) -> usize {
match self {
Self::V0(env) => env.idx,
}
}
pub fn set_idx(&mut self, idx: usize) {
match self {
Self::V0(env) => env.idx = idx,
}
}
pub fn latest_status(&self) -> &async_std::process::ExitStatus {
match self {
Self::V0(env) => &env.latest_status,
}
}
pub fn set_status(&mut self, status: async_std::process::ExitStatus) {
match self {
Self::V0(env) => {
env.latest_status = status;
}
}
}
pub fn current_dir(&self) -> &std::path::Path {
match self {
Self::V0(env) => &env.pwd,
}
}
pub fn set_current_dir(&mut self, pwd: std::path::PathBuf) {
match self {
Self::V0(env) => {
env.pwd = pwd;
}
}
}
pub fn apply(&self, cmd: &mut pty_process::Command) {
match self {
Self::V0(env) => {
cmd.current_dir(&env.pwd);
}
}
}
pub fn update(&mut self) -> anyhow::Result<()> {
self.set_current_dir(std::env::current_dir()?);
Ok(())
}
pub fn as_bytes(&self) -> Vec<u8> {
bincode::serialize(self).unwrap()
}
pub fn from_bytes(bytes: &[u8]) -> Self {
bincode::deserialize(bytes).unwrap()
}
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn serialize_status<S>(
status: &std::process::ExitStatus,
s: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let code: u16 = status.code().unwrap_or(0).try_into().unwrap();
let signal: u16 = status.signal().unwrap_or(0).try_into().unwrap();
s.serialize_u16((code << 8) | signal)
}
fn deserialize_status<'de, D>(
d: D,
) -> Result<std::process::ExitStatus, D::Error>
where
D: serde::Deserializer<'de>,
{
let status = u16::deserialize(d)?;
Ok(std::process::ExitStatus::from_raw(i32::from(status)))
}
|