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
130
131
132
133
134
135
136
137
138
139
//! The write seam a destination is reached through, and the two refusals a source with
//! nothing on one side of the contract answers with.
//!
//! [`TaskSource`](crate::TaskSource) is a read interface, and it stays one for every
//! source that has nothing to write into: both write methods are defaulted, so a source
//! that cannot be written needs no edit and keeps refusing by saying so. What a source
//! opts into is [`WriteSupport::Supported`], and what that opt-in owes is real
//! implementations of [`TaskSource::write_task`](crate::TaskSource::write_task) and
//! [`TaskSource::write_project`](crate::TaskSource::write_project).
use JsonSchema;
use ;
use crate::;
/// Whether a source can be written through at all.
///
/// Deliberately its own enum rather than a reuse of [`Support`](crate::Support): that one
/// says whether a source applies a *predicate* itself, and the engine compensates for an
/// `Unsupported` there by narrowing a wider result. There is no compensating for a
/// destination that cannot be written — the copy is refused, naming the source and the
/// plugin behind it — so conflating the two would invite an engine-side workaround for a
/// case that has none.
/// One create-or-update of a work item at a destination.
///
/// The two cases are one type because a destination decides between them by exactly one
/// question — is there an item here to update — and the engine has already answered it.
/// How large the body one write of an item would store is, as its destination counts it, and
/// the most that destination holds in one.
///
/// The body is the long-form field the destination stores an item's content in — an issue's
/// body, a Linear item's description or content — composed exactly as the write would compose
/// it: the content, the metadata slot the source keeps beside it, and every asset reference
/// rewritten to where the destination serves it. A copy asks for it of every item before it
/// writes any, so an item too large for its destination refuses the copy while nothing of it
/// has been written.
/// The refusal a source with no write side answers a write with.
///
/// Spelled once so every unwritten source refuses in the same words, and so a plugin's
/// refusal and the engine's own message about it cannot describe different things.
/// The refusal a source answers a narrow write of one field of a task with, when it cannot
/// write that field on its own.
///
/// Spelled once beside [`unwritable`] for that function's reason. `field` is the field's own
/// name — `status`, `delivered_by` — so the refusal names what could not be written.
/// The refusal a source with no documents answers a document read with.
///
/// Spelled once beside [`unwritable`], and here rather than beside the reads it answers,
/// because the two are the same kind of thing: a source saying it does not have that side
/// of the contract at all. Every document-free source therefore refuses in the same words,
/// and a plugin's refusal cannot describe something different from the engine's own
/// message about it.
///
/// The two document *writes* reuse [`unwritable`]: a source with no write side refuses a
/// document write for the reason it refuses every other write, and saying it twice in two
/// wordings would make one refusal read as two.