* Map a FpsParseResult failure reason to a human-friendly * error-box message. The empty / undefined / default-fallthrough case * shouldn't be reachable from the CLI flag (citty supplies a default of * "30") but the branch exists so this helper can be reused by other * fps-accepting CLI
(
input: string,
reason: Exclude<FpsParseResult, { ok: true }>["reason"],
)
| 102 | * fps-accepting CLI surfaces in the future. |
| 103 | */ |
| 104 | function formatFpsParseError( |
| 105 | input: string, |
| 106 | reason: Exclude<FpsParseResult, { ok: true }>["reason"], |
| 107 | ): string { |
| 108 | switch (reason) { |
| 109 | case "empty": |
| 110 | return "Frame rate must not be empty."; |
| 111 | case "not-a-number": |
| 112 | return `Got "${input}". Frame rate must be an integer (e.g. 30) or a rational (e.g. 30000/1001 for NTSC).`; |
| 113 | case "non-positive": |
| 114 | return `Got "${input}". Frame rate must be greater than zero.`; |
| 115 | case "out-of-range": |
| 116 | return `Got "${input}". Frame rate must be in the range 1–240.`; |
| 117 | case "invalid-fraction": |
| 118 | return `Got "${input}". Rational frame rates must be two positive integers separated by '/' (e.g. 30000/1001).`; |
| 119 | case "ambiguous-decimal": |
| 120 | return `Got "${input}". Decimal frame rates are ambiguous — use the exact rational form instead (e.g. 30000/1001 for 29.97).`; |
| 121 | } |
| 122 | } |
| 123 | const RENDER_FORMATS = ["mp4", "webm", "mov", "png-sequence", "gif"] as const; |
| 124 | type RenderFormat = (typeof RENDER_FORMATS)[number]; |
| 125 | const VALID_FORMAT = new Set<string>(RENDER_FORMATS); |