switchyard/
lib.rs

1#![deny(unsafe_code)]
2// Tests may use unit-struct defaults and complex types for world/test scaffolding
3#![cfg_attr(
4    test,
5    allow(clippy::default_constructed_unit_structs, clippy::type_complexity)
6)]
7#![doc = include_str!("../README.md")]
8/* ---- unwrap/expect policy ---- */
9// Warn everywhere (incl. tests), but deny in non-test builds.
10#![warn(clippy::unwrap_used, clippy::expect_used)]
11#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))]
12/* ---- dev defaults: useful warnings, not blocking ---- */
13#![warn(
14    // Rustc groups
15    future_incompatible,
16    rust_2018_idioms,
17
18    // API hygiene
19    unreachable_pub,
20    missing_debug_implementations,
21    missing_copy_implementations,
22    trivial_casts,
23    trivial_numeric_casts,
24    unused_import_braces,
25    unused_qualifications,
26
27    // Docs quality
28    rustdoc::broken_intra_doc_links,
29    rustdoc::private_intra_doc_links
30)]
31// Clippy general & hardening (warn by default during dev)
32#![warn(clippy::all, clippy::cargo, clippy::pedantic)]
33#![cfg_attr(
34    not(test),
35    deny(
36        clippy::unwrap_used,
37        clippy::expect_used,
38        clippy::panic,
39        clippy::todo,
40        clippy::unimplemented,
41        clippy::unreachable,
42        clippy::allow_attributes_without_reason,
43        clippy::must_use_candidate,
44        clippy::missing_const_for_fn,
45        clippy::suspicious_open_options,
46        clippy::uninlined_format_args,
47        clippy::missing_errors_doc,
48        clippy::doc_markdown,
49        clippy::too_many_lines,
50        clippy::ref_option,
51        clippy::used_underscore_binding,
52        clippy::manual_let_else,
53        clippy::implicit_clone,
54        clippy::cast_possible_truncation,
55        clippy::cast_possible_wrap,
56        clippy::cast_sign_loss,
57        clippy::cast_precision_loss
58    )
59)]
60#![allow(
61    clippy::multiple_crate_versions,
62    reason = "deps resolved by Cargo, not in our control"
63)]
64/* ---- PROD MODE: turn key warnings into hard errors ----
65   Triggers when either:
66   - feature "prod" is enabled, or
67   - building in release (not(debug_assertions)) — optional, keep if you like.
68*/
69#![cfg_attr(
70    all(not(test), any(feature = "prod", not(debug_assertions))),
71    deny(
72        // rustc / rustdoc
73        future_incompatible,
74        rust_2018_idioms,
75        unreachable_pub,
76        trivial_casts,
77        trivial_numeric_casts,
78        unused_import_braces,
79        unused_qualifications,
80        rustdoc::broken_intra_doc_links,
81        rustdoc::private_intra_doc_links,
82        missing_debug_implementations
83    )
84)]
85#![cfg_attr(
86    all(not(test), any(feature = "prod", not(debug_assertions))),
87    deny(
88        // clippy: panic sources & API hygiene become errors in prod
89        clippy::panic,
90        clippy::panic_in_result_fn,
91        clippy::todo,
92        clippy::unimplemented,
93        clippy::dbg_macro,
94        clippy::indexing_slicing,
95        clippy::allow_attributes_without_reason,
96        clippy::cast_lossless,
97        clippy::cast_possible_truncation,
98        clippy::cast_possible_wrap,
99        clippy::cast_sign_loss,
100        clippy::cast_precision_loss
101    )
102)]
103
104//! Switchyard: safe, atomic, reversible filesystem swaps.
105//!
106//! Safety model highlights:
107//! - All mutations follow a TOCTOU-safe sequence using directory handles (open parent `O_DIRECTORY|O_NOFOLLOW` → *at on final component → renameat → fsync(parent)).
108//! - Public mutating APIs operate on `SafePath` only; internal FS code uses capability-style directory handles.
109//! - This crate forbids `unsafe` and uses `rustix` for syscalls.
110//!
111//! Quickstart (builder is the default way to construct the API):
112//! ```rust,ignore
113//! use switchyard::api::Switchyard;
114//! use switchyard::logging::JsonlSink;
115//! use switchyard::policy::Policy;
116//! let facts = JsonlSink::default();
117//! let audit = JsonlSink::default();
118//! let _api = Switchyard::builder(facts, audit, Policy::default()).build();
119//! ```
120
121pub mod adapters;
122pub mod api;
123pub mod constants;
124pub mod fs;
125pub mod logging;
126pub mod policy;
127pub mod preflight;
128pub mod types;
129
130pub use api::*;