Skip to main content

cargo_plushie/
lib.rs

1//! Shared types and utilities for `cargo plushie`.
2//!
3//! The crate is split between `src/main.rs` (CLI entry point + clap
4//! parsing) and this library module. Keeping the logic in a library
5//! makes integration testing possible without spawning the binary.
6//!
7//! Commands:
8//!
9//! - `cargo plushie build` - generate a custom renderer workspace
10//!   under `target/plushie-renderer/` with every native widget in the
11//!   dep graph registered, then run `cargo build`.
12//! - `cargo plushie download` - fetch a precompiled stock renderer
13//!   from GitHub releases and place it under `target/plushie/bin/`.
14
15#![deny(missing_docs)]
16
17/// Metadata describing a single native widget as declared in its
18/// `[package.metadata.plushie.widget]` table.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct WidgetMetadata {
21    /// Cargo package name.
22    pub crate_name: String,
23    /// On-disk path to the widget crate's manifest directory.
24    pub crate_path: std::path::PathBuf,
25    /// Wire-protocol type name registered by the widget.
26    pub type_name: String,
27    /// Rust constructor expression (e.g. `my_gauge::Gauge::new()`).
28    pub constructor: String,
29}
30
31/// Error type returned by library functions in this crate.
32#[derive(Debug, thiserror::Error)]
33#[non_exhaustive]
34pub enum Error {
35    /// Cargo metadata failed to produce a dep graph.
36    #[error("cargo metadata failed: {0}")]
37    CargoMetadata(String),
38    /// A widget crate declared an incomplete or invalid
39    /// `[package.metadata.plushie.widget]` table.
40    #[error("invalid widget metadata for `{crate_name}`: {reason}")]
41    InvalidWidgetMetadata {
42        /// Cargo package whose manifest was malformed.
43        crate_name: String,
44        /// Human-readable description of what was missing or wrong.
45        reason: String,
46    },
47    /// Two widgets declared the same `type_name`.
48    #[error("widget type name `{type_name}` is registered by multiple crates: {crates}")]
49    DuplicateTypeName {
50        /// The colliding wire-protocol type name.
51        type_name: String,
52        /// Comma-separated list of crate names in collision.
53        crates: String,
54    },
55    /// A widget declared a type name that is already registered by the
56    /// built-in iced widget set.
57    #[error(
58        "widget `{crate_name}` declares type name `{type_name}` which shadows a built-in widget"
59    )]
60    BuiltinCollision {
61        /// Cargo package responsible for the collision.
62        crate_name: String,
63        /// Wire-protocol type name that conflicts with a built-in.
64        type_name: String,
65    },
66    /// Two widgets produced the same crate basename.
67    #[error("widget crate basename `{basename}` is shared by multiple crates: {crates}")]
68    DuplicateCrateBasename {
69        /// The crate basename that collided.
70        basename: String,
71        /// Comma-separated list of crate names / paths in collision.
72        crates: String,
73    },
74    /// A widget's `constructor` expression does not look like a valid
75    /// Rust path + optional parenthesized call.
76    #[error(
77        "widget `{crate_name}` constructor `{constructor}` is not a valid Rust \
78         identifier path (expected `module::Type::fn()` or similar)"
79    )]
80    InvalidConstructor {
81        /// Widget crate name.
82        crate_name: String,
83        /// Constructor expression that failed validation.
84        constructor: String,
85    },
86    /// Generic I/O failure during build or download.
87    #[error("io error: {0}")]
88    Io(#[from] std::io::Error),
89    /// Inner `cargo build` invocation exited with a non-zero status.
90    #[error("`cargo build` failed with status {0}")]
91    CargoBuildFailed(std::process::ExitStatus),
92    /// A `cargo plushie download` call found native widgets in the
93    /// dep graph; the stock binary cannot register them.
94    #[error(
95        "native widgets detected ({widgets}); stock binary cannot register them. \
96         Run `cargo plushie build` to produce a custom renderer instead."
97    )]
98    DownloadWithNativeWidgets {
99        /// Comma-separated list of native widget crate names.
100        widgets: String,
101    },
102    /// Any other error surfaced through `anyhow`.
103    #[error(transparent)]
104    Other(#[from] anyhow::Error),
105}
106
107/// Convenience `Result` alias.
108pub type Result<T> = std::result::Result<T, Error>;
109
110pub mod discover;
111pub mod doctor;
112pub mod download;
113pub mod generator;
114pub mod patch_config;
115pub mod platform;
116pub mod scaffold;