Skip to main content

line_editor/
types.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bstr::{BStr, BString};
6use std::fmt;
7
8/// Errors that can occur during line reading.
9#[derive(Debug)]
10pub enum ReadlineError {
11    /// End of file reached (e.g., Ctrl-D on an empty line).
12    Eof,
13    /// Line reading was interrupted (e.g., Ctrl-C).
14    Interrupted,
15    /// An I/O error occurred while reading or writing.
16    Io(std::io::Error),
17}
18
19impl fmt::Display for ReadlineError {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        match self {
22            Self::Eof => write!(f, "End of file"),
23            Self::Interrupted => write!(f, "Interrupted"),
24            Self::Io(err) => write!(f, "I/O error: {err}"),
25        }
26    }
27}
28
29impl std::error::Error for ReadlineError {
30    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
31        match self {
32            Self::Io(err) => Some(err),
33            _ => None,
34        }
35    }
36}
37
38impl From<std::io::Error> for ReadlineError {
39    fn from(err: std::io::Error) -> Self {
40        Self::Io(err)
41    }
42}
43
44/// Standard ANSI colors for hint text.
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum Color {
47    /// Standard Black (ANSI 30)
48    Black,
49    /// Standard Red (ANSI 31)
50    Red,
51    /// Standard Green (ANSI 32)
52    Green,
53    /// Standard Yellow (ANSI 33)
54    Yellow,
55    /// Standard Blue (ANSI 34)
56    Blue,
57    /// Standard Magenta (ANSI 35)
58    Magenta,
59    /// Standard Cyan (ANSI 36)
60    Cyan,
61    /// Standard White (ANSI 37)
62    White,
63    /// Custom ANSI color code
64    Custom(u8),
65}
66
67impl Color {
68    /// Converts this color to its ANSI numeric code.
69    pub fn to_ansi_code(&self) -> u8 {
70        match self {
71            Self::Black => 30,
72            Self::Red => 31,
73            Self::Green => 32,
74            Self::Yellow => 33,
75            Self::Blue => 34,
76            Self::Magenta => 35,
77            Self::Cyan => 36,
78            Self::White => 37,
79            Self::Custom(code) => *code,
80        }
81    }
82
83    /// Creates a `Color` from an ANSI numeric code.
84    pub fn from_ansi_code(code: u8) -> Self {
85        match code {
86            30 => Self::Black,
87            31 => Self::Red,
88            32 => Self::Green,
89            33 => Self::Yellow,
90            34 => Self::Blue,
91            35 => Self::Magenta,
92            36 => Self::Cyan,
93            37 => Self::White,
94            c => Self::Custom(c),
95        }
96    }
97}
98
99impl From<u8> for Color {
100    fn from(code: u8) -> Self {
101        Self::from_ansi_code(code)
102    }
103}
104
105/// Represents an inline hint displayed alongside the input buffer.
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct Hint {
108    /// Text of the hint.
109    pub text: BString,
110    /// Optional color of the hint text.
111    pub color: Option<Color>,
112    /// Whether the hint text should be displayed in bold.
113    pub bold: bool,
114}
115
116impl Hint {
117    /// Creates a new hint with default styling (no color, not bold).
118    pub fn new(text: impl Into<BString>) -> Self {
119        Self { text: text.into(), color: None, bold: false }
120    }
121
122    /// Sets the color of the hint.
123    pub fn with_color(mut self, color: impl Into<Color>) -> Self {
124        self.color = Some(color.into());
125        self
126    }
127
128    /// Sets whether the hint should be displayed in bold.
129    pub fn with_bold(mut self, bold: bool) -> Self {
130        self.bold = bold;
131        self
132    }
133}
134
135/// Closure type for tab completion handlers.
136pub trait CompletionHandler: Fn(&BStr) -> Vec<BString> + Send + Sync {}
137impl<F: Fn(&BStr) -> Vec<BString> + Send + Sync> CompletionHandler for F {}
138
139/// Closure type for inline hint handlers.
140pub trait HintHandler: Fn(&BStr) -> Option<Hint> + Send + Sync {}
141impl<F: Fn(&BStr) -> Option<Hint> + Send + Sync> HintHandler for F {}