docs: add lib docs

This commit is contained in:
Kristofers Solo 2025-07-14 21:30:58 +03:00
parent cd8fd27e69
commit 748db052ff
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
2 changed files with 128 additions and 13 deletions

View File

@ -9,7 +9,7 @@ env:
RUSTFLAGS: --deny warnings
RUSTDOCFLAGS: --deny warnings
jobs:
# Run tests.
# Run tests
test:
name: Tests
runs-on: ubuntu-latest
@ -20,17 +20,29 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
libasound2-dev libudev-dev libwayland-dev \
libxkbcommon-dev
- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
sweep-cache: true
- name: Run tests
- name: Install cargo-nextest
run: cargo install cargo-nextest --locked
- name: Run tests with nextest
run: |
cargo test --locked --workspace --all-features --all-targets
cargo nextest run \
--all-features \
--all-targets
# Workaround for https://github.com/rust-lang/cargo/issues/6669
cargo test --locked --workspace --all-features --doc
# Run clippy lints.
cargo test \
--locked \
--workspace \
--all-features \
--doc
# Run clippy lints
clippy:
name: Clippy
runs-on: ubuntu-latest
@ -43,14 +55,24 @@ jobs:
with:
components: clippy
- name: Install dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
libasound2-dev libudev-dev libwayland-dev \
libxkbcommon-dev
- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
sweep-cache: true
- name: Run clippy lints
run: cargo clippy --locked --workspace --all-features -- --deny warnings
# Check formatting.
run: |
cargo clippy \
--locked \
--workspace \
--all-features \
-- \
--deny warnings
# Check formatting
format:
name: Format
runs-on: ubuntu-latest
@ -63,8 +85,12 @@ jobs:
with:
components: rustfmt
- name: Run cargo fmt
run: cargo fmt --all -- --check
# Check documentation.
run: |
cargo fmt \
--all \
-- \
--check
# Check documentation
doc:
name: Docs
runs-on: ubuntu-latest
@ -75,10 +101,22 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
libasound2-dev libudev-dev libwayland-dev \
libxkbcommon-dev
- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
sweep-cache: true
- name: Check documentation
run: cargo doc --locked --workspace --all-features --document-private-items --no-deps
run: |
cargo doc \
--locked \
--workspace \
--all \
--features \
--document-private \
--items \
--no-deps

View File

@ -1,3 +1,76 @@
//! # filecaster
//!
//! `filecaster` is a small `proc-macro` crate that provides a derivemacro
//! `#[derive(FromFile)]` to make it trivial to load partial configurations
//! from files, merge them with defaults, and get a fullypopulated struct.
//!
//! ## What it does
//!
//! For any struct with named fields, `#[derive(FromFile)]` generates:
//!
//! 1. A companion `<YourStruct>NameFile` struct in which each field is wrapped
//! in `Option<...>`.
//! 2. A constructor `YourStruct::from_file(file: Option<YourStructFile>) -> YourStruct`
//! that takes your partiallyfilled file struct, fills in `None` fields
//! with either:
//! - an expression you supply via `#[from_file(default = ...)]`, or
//! - `Default::default()` (requires `T: Default`)
//! 3. An implementation of `From<Option<YourStructFile>> for YourStruct`.
//!
//! Because each field in the filestruct is optional, you can deserialize
//! e.g. JSON, YAML or TOML into it via Serde, then call `.from_file(...)`
//! to get your final struct.
//!
//! ## Optional perfield defaults
//!
//! Use a `#[from_file(default = <expr>)]` attribute on any field to override
//! the fallback value. You may supply any expression valid in that structs
//! context. If you omit it, the macro will require `T: Default` and call
//! `unwrap_or_default()`.
//!
//! Example:
//!
//! ```rust
//! use from_file::FromFile;
//!
//! #[derive(Debug, Clone, FromFile)]
//! #[serde(default)]
//! struct AppConfig {
//! /// If the user does not specify a host, use `"127.0.0.1"`.
//! #[from_file(default = "127.0.0.1")]
//! host: String,
//!
//! /// Number of worker threads; defaults to `4`.
//! #[from_file(default = 4)]
//! workers: usize,
//!
//! /// If not set, use `false`.
//! auto_reload: bool, // requires `bool: Default`
//! }
//!
//! // After deserializing the partial config from disk (e.g. with Serde):
//! let file: Option<AppConfigFile> = serde_yaml::from_str(yaml_text).ok();
//! let cfg: AppConfig = AppConfig::from_file(file);
//! println!("{cfg:#?}");
//! ```
//!
//! ## Feature flags
//!
//! - `merge`
//! If you enable the `merge` feature, the generated `<Name>File` struct will
//! also derive `merge::Merge`, and you can layer multiple partial files
//! together before calling `.from_file(...)`. Any fieldlevel merge strategy
//! annotations (`#[merge(...)]`) are applied automatically.
//!
//! ## Limitations
//!
//! - Only works on structs with _named_ fields (no tuplestructs or enums).
//! - All fields without a `#[from_file(default = ...)]` must implement `Default`.
//!
//! ## License
//!
//! MIT OR Apache-2.0
mod from_file;
pub(crate) use from_file::impl_from_file;
@ -5,6 +78,10 @@ use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
use syn::{DeriveInput, parse_macro_input};
/// Implements the `FromFile` derive macro.
///
/// This macro processes the `#[from_file]` attribute on structs to generate
/// code for loading data from files.
#[proc_macro_error]
#[proc_macro_derive(FromFile, attributes(from_file))]
pub fn derive_from_file(input: TokenStream) -> TokenStream {