Skip to main content

fc_dioxus/core/
state.rs

1//! State shared across components, without inventing new upstream values.
2
3use super::id::Id;
4use dioxus::prelude::EventHandler;
5
6/// The orientation of a component.
7#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
8#[non_exhaustive]
9pub enum Orientation {
10    /// A horizontal separator or row.
11    #[default]
12    Horizontal,
13    /// A vertical separator or column.
14    Vertical,
15}
16
17/// Whether a control can be activated, and whether it remains discoverable.
18#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
19#[non_exhaustive]
20pub enum Availability {
21    /// The action is available.
22    #[default]
23    Enabled,
24    /// Native disabled state, removed from sequential focus.
25    Disabled,
26    /// Focusable but inactive; visible explanatory text is referenced by ID.
27    Unavailable {
28        /// ID of the element explaining the unavailable action.
29        reason: Id,
30    },
31}
32impl Availability {
33    /// Drop activation handlers for both forms of unavailability.
34    #[must_use]
35    pub fn guard<T: 'static>(&self, handler: Option<EventHandler<T>>) -> Option<EventHandler<T>> {
36        if *self == Self::Enabled {
37            handler
38        } else {
39            None
40        }
41    }
42}
43
44/// Upstream's lifecycle vocabulary.
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46#[non_exhaustive]
47pub enum Lifecycle {
48    /// Not yet scheduled.
49    Pending,
50    /// Waiting to execute.
51    Queued,
52    /// Incremental output is arriving.
53    Streaming,
54    /// Work is executing.
55    Running,
56    /// Work completed.
57    Complete,
58    /// Work was cancelled.
59    Aborted,
60    /// Permission was denied.
61    Denied,
62    /// Work failed.
63    Error,
64}
65impl Lifecycle {
66    /// Every state, in lifecycle order.
67    pub const ALL: &'static [Self] = &[
68        Self::Pending,
69        Self::Queued,
70        Self::Streaming,
71        Self::Running,
72        Self::Complete,
73        Self::Aborted,
74        Self::Denied,
75        Self::Error,
76    ];
77    /// Whether the work has finished, one way or another.
78    #[must_use]
79    pub const fn is_settled(self) -> bool {
80        matches!(
81            self,
82            Self::Complete | Self::Aborted | Self::Denied | Self::Error
83        )
84    }
85    /// The upstream attribute value.
86    #[must_use]
87    pub const fn as_str(self) -> &'static str {
88        match self {
89            Self::Pending => "pending",
90            Self::Queued => "queued",
91            Self::Streaming => "streaming",
92            Self::Running => "running",
93            Self::Complete => "complete",
94            Self::Aborted => "aborted",
95            Self::Denied => "denied",
96            Self::Error => "error",
97        }
98    }
99}
100
101/// The author role in upstream's message contract.
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103#[non_exhaustive]
104pub enum MessageRole {
105    /// User-authored message.
106    User,
107    /// Assistant-authored message.
108    Assistant,
109    /// System message.
110    System,
111    /// Tool result.
112    Tool,
113}
114impl MessageRole {
115    /// The upstream attribute value.
116    #[must_use]
117    pub const fn as_str(self) -> &'static str {
118        match self {
119            Self::User => "user",
120            Self::Assistant => "assistant",
121            Self::System => "system",
122            Self::Tool => "tool",
123        }
124    }
125}
126
127/// A semantic HTML heading rank.
128#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
129#[non_exhaustive]
130pub enum HeadingLevel {
131    /// Level 1 heading.
132    H1,
133    /// Level 2 heading.
134    H2,
135    /// Level 3 heading.
136    #[default]
137    H3,
138    /// Level 4 heading.
139    H4,
140    /// Level 5 heading.
141    H5,
142    /// Level 6 heading.
143    H6,
144}