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
//! Where a command's text payload comes from.
//!
//! Two ways in, and both live here so every command answers them the same
//! way. [`resolve`] handles the explicit pair — a value flag and its
//! `--*-file` sibling, with a bare `-` meaning stdin on either.
//! [`fallback`] handles the implicit one: when the primary text argument is
//! absent AND stdin is piped/redirected, the text comes from stdin — `echo
//! note | cliban issue log KEY` just works, no `--message-file -`
//! incantation.
//!
//! This is the binary's one sanctioned `is_terminal()` check on STDIN. It is
//! deliberately separate from the output contract in `crate::output`: that
//! resolver decides how results are *printed* (and owns the stdout check);
//! this one only decides whether piped *input* exists to read. Callers must
//! consult it ONLY when every explicit source (positional, `--*-file`) is
//! absent — explicit input always wins — and a TTY returns `None` so the
//! caller keeps its fast "required" validation error instead of blocking on
//! input the user never intended to type.
use crate;
use ;
/// `Ok(None)` when stdin is a terminal; otherwise the full piped/redirected
/// contents. An empty pipe yields `Some("")` — whether that is a validation
/// error (log, append-section) or simply "no body" (project note add) is the
/// caller's contract, not ours.
/// Resolves a text payload from a value flag and its `--*-file` sibling.
///
/// The two are mutually exclusive, and a bare `-` on *either* is the stdin
/// sentinel — `--body -` and `--body-file -` both read the pipe. Only an
/// exact `-` counts, so a markdown bullet (`- a lesson`) stays literal.
///
/// `Ok(None)` means the caller passed neither. What that means is the
/// caller's contract, not this function's: leave-unchanged for `edit`, empty
/// for `add`, or defer to [`fallback`] for `project note add`.
///
/// `value_flag` / `file_flag` name the flags in the mutual-exclusion error,
/// so `note add` says `--body` rather than some other command's spelling.
///
/// The sentinel belongs to *flags*, not positionals: `issue log KEY -` logs a
/// dash, because a positional payload has no second spelling to disambiguate
/// it from. Those commands read their file arm through [`read_stdin`] and
/// their bare pipe through [`fallback`].
/// Where a `log`-shaped command's entry comes from: a positional message, a
/// `--message-file` sibling (with `-` for stdin), or — when neither was
/// given — a bare pipe. Never empty: an entry nobody wrote is a refusal, not
/// a blank line spliced into someone's `## Activity Log`.
///
/// Shared because `issue log` and `milestone log` splice the identical line
/// into the identical section grammar, so they must also agree on where that
/// line comes from. Two spellings of "where does the message come from" would
/// drift, and the drift would only show up as one of them silently accepting
/// input the other refused.
///
/// Unlike [`resolve`], a bare `-` in the *positional* stays literal: a
/// positional payload has no second spelling to disambiguate it from, so
/// `cliban issue log KEY -` logs a dash.
/// Unconditional read of stdin — the `-` sentinel says the user meant it, so
/// there is no `is_terminal` check here and a bare `-` at a terminal waits
/// for input, as `cat -` does.