memstead_base/ops/transport.rs
1//! Wire types for the three transport ops `Engine::fetch`,
2//! `Engine::pull`, `Engine::push`.
3//!
4//! `branch_reset` lives next to these in the transport surface;
5//! this file pins the success-path payloads each transport op
6//! returns.
7
8use serde::{Deserialize, Serialize};
9
10/// Outcome of `Engine::fetch`. Updates remote-tracking refs without
11/// moving the local branch pointer.
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13pub struct FetchOutcome {
14 /// Remote name the fetch targeted (verbatim from input).
15 pub remote: String,
16 /// Refspecs that were fetched. Empty in the response means "the
17 /// remote's configured defaults"; otherwise echoes the caller's
18 /// list.
19 pub refspecs: Vec<String>,
20 /// Per-ref tip the fetch landed on, keyed by remote-tracking ref
21 /// (e.g. `refs/remotes/origin/specs` → new SHA). Only refs that
22 /// actually moved appear here; unchanged refs are omitted.
23 pub updated_refs: Vec<UpdatedRef>,
24}
25
26/// One ref's transition recorded by a successful fetch / pull.
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
28pub struct UpdatedRef {
29 /// Ref name (e.g. `refs/remotes/origin/specs`).
30 pub ref_name: String,
31 /// SHA the ref pointed at before this op, when known. Empty
32 /// string when the ref did not exist locally before the op.
33 pub previous_sha: String,
34 /// SHA the ref points at after this op.
35 pub new_sha: String,
36}
37
38/// Outcome of `Engine::pull`. Fast-forwards the local branch when
39/// possible; refuses with `LOCAL_DIVERGENCE` on a diverged local
40/// branch.
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
42pub struct PullOutcome {
43 /// Mem whose branch was advanced.
44 pub mem: String,
45 /// Remote-tracking ref the fast-forward consumed (e.g.
46 /// `refs/remotes/origin/specs`).
47 pub source_ref: String,
48 /// Local branch ref that was moved (e.g. `refs/heads/specs`).
49 pub branch_ref: String,
50 /// SHA the local branch pointed at before the pull. Empty for a
51 /// fresh branch that did not yet exist locally.
52 pub previous_sha: String,
53 /// SHA the local branch points at after the pull.
54 pub new_sha: String,
55 /// Updated remote-tracking refs the underlying fetch produced.
56 pub updated_refs: Vec<UpdatedRef>,
57}
58
59/// Outcome of `Engine::push`. The remote's view of the mem's
60/// branch has moved to `new_sha` after the operation.
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
62pub struct PushOutcome {
63 /// Mem whose branch was pushed.
64 pub mem: String,
65 /// Remote name the push targeted.
66 pub remote: String,
67 /// Local branch ref that was pushed (e.g. `refs/heads/specs`).
68 pub branch_ref: String,
69 /// SHA the remote acknowledged after the push.
70 pub new_sha: String,
71 /// `true` when the push was a force update (the caller passed
72 /// `force: true` and the underlying ref move was not a
73 /// fast-forward). Consumers warn on this in their UI.
74 pub forced: bool,
75}
76
77/// Outcome of `Engine::push_all`: every mounted git-branch mem's
78/// declared branch plus the `__MEMSTEAD` ref of each mem-repo,
79/// pushed fast-forward only. The run never stops at the first
80/// refusal — a ref that cannot move lands in `refused` and the
81/// remaining refs are still attempted, so one diverged branch never
82/// holds back the publication of the others. A ref already at the
83/// remote's SHA is recorded in `in_sync` and not pushed.
84#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
85pub struct PushAllOutcome {
86 /// Remote name the run targeted.
87 pub remote: String,
88 /// Refs the remote now carries at a new SHA, in push order.
89 pub pushed: Vec<PushedRef>,
90 /// Refs whose local and remote SHA already agreed — nothing was
91 /// sent for them.
92 pub in_sync: Vec<String>,
93 /// Refs the run could not move, each with its typed code.
94 pub refused: Vec<RefusedRef>,
95}
96
97/// One ref `Engine::push_all` moved on the remote.
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99pub struct PushedRef {
100 /// Full ref name (e.g. `refs/heads/specs`, `refs/heads/__MEMSTEAD`).
101 pub ref_name: String,
102 /// Mem the ref belongs to; `None` for the `__MEMSTEAD` ref.
103 pub mem: Option<String>,
104 /// SHA the remote held before the push. Empty when the remote
105 /// did not carry the ref yet.
106 pub previous_sha: String,
107 /// SHA the remote acknowledged after the push.
108 pub new_sha: String,
109}
110
111/// One ref `Engine::push_all` could not move.
112#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
113pub struct RefusedRef {
114 /// Full ref name the refusal is about.
115 pub ref_name: String,
116 /// Mem the ref belongs to; `None` for the `__MEMSTEAD` ref.
117 pub mem: Option<String>,
118 /// Typed refusal code (`NON_FAST_FORWARD`, `LOCAL_INVALID_STATE`,
119 /// `UNKNOWN_REF`, …) — the same vocabulary the single-mem push
120 /// returns as an error.
121 pub code: String,
122 /// The refusal's human message.
123 pub message: String,
124}
125
126/// Outcome of `Engine::remote_add`. Configures a named remote on the
127/// workspace's mem-repo so `fetch` / `pull` / `push` have somewhere to
128/// go — upsert semantics (re-pointing an existing remote is not an
129/// error; `updated` says which happened).
130#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
131pub struct RemoteAddOutcome {
132 /// Remote name (verbatim from input).
133 pub remote: String,
134 /// URL the remote now points at.
135 pub url: String,
136 /// `true` when the remote already existed and its URL was
137 /// re-pointed; `false` when it was newly added.
138 pub updated: bool,
139}