pub struct App<D: Document> { /* private fields */ }Expand description
An app: name, document type and format, commands, views. run() opens the window; the same
definition serves the CLI and MCP (App::cli) and tests (App::headless).
use ashlar_app::{App, Cx, Session};
use ashlar_command::{CommandError, CommandSpec};
#[derive(Clone, Default, serde::Serialize, serde::Deserialize)]
struct Doc { count: i64 }
fn bump(s: &mut Session<Doc>, _: &serde_json::Value) -> Result<serde_json::Value, CommandError> {
s.edit("Bump", |d| d.count += 1);
Ok(serde_json::Value::Null)
}
fn main() -> Result<(), ashlar_app::Error> {
App::<Doc>::new("counter", "0.1.0")
.command(CommandSpec::new("count.bump", "Bump", bump).menu(&["Edit"]).shortcut("Mod+B"))
.view(|ui, cx: &mut Cx<'_, Doc>| {
ui.label(format!("{}", cx.doc().count));
if ui.button("Bump").clicked() {
cx.dispatch("count.bump", serde_json::json!({}));
}
})
.run()
}Implementations§
Source§impl<D: Document> App<D>
impl<D: Document> App<D>
Sourcepub fn new(name: impl Into<String>, version: impl Into<String>) -> Self
pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self
An app called name (lower case, used for folders, env vars and the CLI).
Sourcepub fn organization(
self,
qualifier: impl Into<String>,
org: impl Into<String>,
) -> Self
pub fn organization( self, qualifier: impl Into<String>, org: impl Into<String>, ) -> Self
Reverse-domain qualifier and organisation for the OS folders ("com", "Acme").
Sourcepub fn format(self, format: Format<D>) -> Self
pub fn format(self, format: Format<D>) -> Self
The document’s file format, with its migrations.
Sourcepub fn file_extension(self, ext: impl Into<String>) -> Self
pub fn file_extension(self, ext: impl Into<String>) -> Self
A file extension offered by Open and Save dialogs (without the dot).
Sourcepub fn commands(
self,
specs: impl IntoIterator<Item = CommandSpec<Session<D>>>,
) -> Self
pub fn commands( self, specs: impl IntoIterator<Item = CommandSpec<Session<D>>>, ) -> Self
Add commands (menus follow declaration order).
pub fn command(self, spec: CommandSpec<Session<D>>) -> Self
Sourcepub fn view(self, view: impl FnMut(&mut Ui, &mut Cx<'_, D>) + 'static) -> Self
pub fn view(self, view: impl FnMut(&mut Ui, &mut Cx<'_, D>) + 'static) -> Self
The UI, drawn inside the window’s central area each frame.
Sourcepub fn setup(self, f: impl FnOnce(&Context) + 'static) -> Self
pub fn setup(self, f: impl FnOnce(&Context) + 'static) -> Self
Runs once before the first frame (install fonts, tokens).
Sourcepub fn autosave(self, every: Option<Duration>) -> Self
pub fn autosave(self, every: Option<Duration>) -> Self
Autosave interval (None: no autosave or recovery). Default 60 s.
Sourcepub fn telemetry(self, key: impl Into<String>, endpoint: Option<&str>) -> Self
pub fn telemetry(self, key: impl Into<String>, endpoint: Option<&str>) -> Self
Telemetry (with the telemetry feature): write key and server. Always on when endpoint
is set (no notice, no switches); TRACER_DISABLED in the environment turns it off.
Sourcepub fn instructions(self, text: impl Into<String>) -> Self
pub fn instructions(self, text: impl Into<String>) -> Self
What MCP clients are told about the app.
Sourcepub fn dirs(self, dirs: AppDirs) -> Self
pub fn dirs(self, dirs: AppDirs) -> Self
Put config, data, cache and logs here instead of the OS folders (tests, portable).
pub fn window_size(self, width: f32, height: f32) -> Self
Sourcepub fn control_port(self, port: u16) -> Self
pub fn control_port(self, port: u16) -> Self
Serve the control port on this port (also --control <port> and <APP>_CONTROL_PORT).
Sourcepub fn headless(self) -> Headless<D>
pub fn headless(self) -> Headless<D>
A session without a window, driving the same commands (tests, scripts).
Sourcepub fn runtime(self) -> Runtime<D>
pub fn runtime(self) -> Runtime<D>
The runtime without a window, for tests and benches: drive it with crate::Driver.
Sourcepub fn cli(self) -> Cli
pub fn cli(self) -> Cli
The app’s -cli binary: commands, exec, run, mcp, serve, version, each on a
fresh headless session (or the running app with --connect PORT). Add app verbs to the
returned ashlar_cli::Cli before run().
Auto Trait Implementations§
impl<D> !RefUnwindSafe for App<D>
impl<D> !Send for App<D>
impl<D> !Sync for App<D>
impl<D> !UnwindSafe for App<D>
impl<D> Freeze for App<D>
impl<D> Unpin for App<D>
impl<D> UnsafeUnpin for App<D>where
Option<Format<D>>: UnsafeUnpin,
Vec<CommandSpec<Session<D>>>: UnsafeUnpin,
Option<Box<dyn FnMut(&mut Ui, &mut Cx<'_, D>)>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more