Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ or `solverforge-solver` differs from `crates/<crate>/public-api.txt`. A change
that adds, removes or changes a public item regenerates that snapshot with
`python3 scripts/check-public-api.py --bless` in the same commit, so review
sees the surface change. Inside those crates, `pub` means supported surface:
`#![warn(unreachable_pub)]` is on, implementation modules are private, and
`unreachable_pub = "warn"` is set in their Cargo `[lints]` tables, implementation modules are private, and
`solverforge-solver` exports every supported item once, at its root.

When a public API change also affects how users discover or reason about the
Expand Down Expand Up @@ -357,15 +357,22 @@ Avoid `#[derive(Clone)]` on generic types when it would introduce unnecessary bo

## Code Organization

- Keep `mod.rs` files limited to module declarations and re-exports.
- Keep every `mod.rs` and `lib.rs` limited to module declarations and `use`
re-exports: no functions, types, impls, constants, macro definitions,
inline module bodies or crate-level attributes. `planning_model!`
manifests and the proc-macro entry points Rust requires in
`solverforge-macros/src/lib.rs` are the only exceptions; lint levels live in
each crate's Cargo `[lints]` table.
- Crate roots document the crate with inner `//!` doc comments and public
items use `///` (or `/** */`); plain `//` and `/* */` comments never
replace them. docs.rs renders only doc comments, so a comment-style sweep
must leave them in place. Every crate in the workspace (`solverforge`,
`solverforge-core`, `solverforge-config`, `solverforge-scoring`,
`solverforge-solver`, `solverforge-console`, `solverforge-macros`,
`solverforge-bridge` and `solverforge-cvrp`) warns on `missing_docs`, so
every new public item needs a doc comment.
`solverforge-bridge` and `solverforge-cvrp`) warns on `missing_docs` through
its Cargo `[lints]` table, which also covers its integration tests, so
every new public item, test crate root and test fixture needs a doc
comment.
- Move implementation code into dedicated files.
- Keep Rust source and test files under 500 LOC. When a module grows beyond
that boundary, split it by subsystem or behavior into adjacent implementation
Expand Down
3 changes: 3 additions & 0 deletions crates/solverforge-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ solverforge-config = { version = "=0.25.1", path = "../solverforge-config" }
solverforge-core = { version = "=0.25.1", path = "../solverforge-core" }
solverforge-scoring = { version = "=0.25.1", path = "../solverforge-scoring" }
solverforge-solver = { version = "=0.25.1", path = "../solverforge-solver" }

[lints.rust]
missing_docs = "warn"
2 changes: 0 additions & 2 deletions crates/solverforge-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
//! dynamic state without pretending that one host-language entity class maps to
//! one concrete Rust entity type.

#![warn(missing_docs)]

mod backend;
mod ids;
mod runner;
Expand Down
3 changes: 3 additions & 0 deletions crates/solverforge-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ description = "Configuration system for SolverForge constraint solver"
serde.workspace = true
toml.workspace = true
thiserror.workspace = true

[lints.rust]
missing_docs = "warn"
2 changes: 0 additions & 2 deletions crates/solverforge-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
//! }
//! ```

#![warn(missing_docs)]

mod acceptor;
mod director;
mod error;
Expand Down
3 changes: 3 additions & 0 deletions crates/solverforge-console/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ num-format = "0.4.4"

[features]
verbose-logging = []

[lints.rust]
missing_docs = "warn"
2 changes: 0 additions & 2 deletions crates/solverforge-console/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
//! - **DEBUG**: Progress updates (1/sec with speed and score)
//! - **TRACE**: Individual step evaluations

#![warn(missing_docs)]

mod banner;
mod format;
mod init;
Expand Down
7 changes: 7 additions & 0 deletions crates/solverforge-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ serde = { workspace = true, optional = true }

[dev-dependencies]
toml.workspace = true

[lints.rust]
missing_docs = "warn"
unreachable_pub = "warn"

[lints.clippy]
type_complexity = "allow"
3 changes: 2 additions & 1 deletion crates/solverforge-core/WIREFRAME.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ src/
│ │ ├── problem_fact.rs — ProblemFactDescriptor struct
│ │ ├── var_descriptor.rs — VariableDescriptor struct
│ │ └── tests/
│ │ ├── mod.rs — Shared test helpers and module declarations
│ │ ├── mod.rs — Test module declarations and shared imports
│ │ ├── fixtures.rs — Shared TestEntity/TestSolution fixtures and entity descriptor builder
│ │ ├── entity_descriptor.rs — EntityDescriptor tests
│ │ ├── solution_descriptor.rs — SolutionDescriptor tests
│ │ └── variable_descriptor.rs — VariableDescriptor tests
Expand Down
39 changes: 39 additions & 0 deletions crates/solverforge-core/src/domain/descriptor/tests/fixtures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! Shared descriptor test fixtures: a one-variable entity and its solution.

use crate::domain::descriptor::*;
use crate::domain::EntityCollectionExtractor;

#[derive(Clone, Debug)]
pub(super) struct TestEntity {
pub id: i64,
pub row: Option<i32>,
}

#[derive(Clone, Debug)]
pub(super) struct TestSolution {
pub entities: Vec<TestEntity>,
}

pub(super) fn get_entities(s: &TestSolution) -> &Vec<TestEntity> {
&s.entities
}

pub(super) fn get_entities_mut(s: &mut TestSolution) -> &mut Vec<TestEntity> {
&mut s.entities
}

pub(super) fn create_test_entity_descriptor() -> EntityDescriptor {
let extractor = Box::new(EntityCollectionExtractor::new(
"TestEntity",
"entities",
get_entities,
get_entities_mut,
));

EntityDescriptor::new(
"TestEntity",
std::any::TypeId::of::<TestEntity>(),
"entities",
)
.with_extractor(extractor)
}
39 changes: 2 additions & 37 deletions crates/solverforge-core/src/domain/descriptor/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,11 @@
// Tests for descriptor types.

mod entity_descriptor;
mod fixtures;
mod solution_descriptor;
mod variable_descriptor;

use crate::domain::descriptor::*;
use crate::domain::EntityCollectionExtractor;
use fixtures::*;
use std::any::Any;

// Shared test helpers used across descriptor test modules.

#[derive(Clone, Debug)]
pub(super) struct TestEntity {
pub id: i64,
pub row: Option<i32>,
}

#[derive(Clone, Debug)]
pub(super) struct TestSolution {
pub entities: Vec<TestEntity>,
}

pub(super) fn get_entities(s: &TestSolution) -> &Vec<TestEntity> {
&s.entities
}

pub(super) fn get_entities_mut(s: &mut TestSolution) -> &mut Vec<TestEntity> {
&mut s.entities
}

pub(super) fn create_test_entity_descriptor() -> EntityDescriptor {
let extractor = Box::new(EntityCollectionExtractor::new(
"TestEntity",
"entities",
get_entities,
get_entities_mut,
));

EntityDescriptor::new(
"TestEntity",
std::any::TypeId::of::<TestEntity>(),
"entities",
)
.with_extractor(extractor)
}
3 changes: 0 additions & 3 deletions crates/solverforge-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
trait bounds from phantom type parameters. Clippy's type_complexity lint
triggers on these tuples but the pattern is architecturally required.
*/
#![allow(clippy::type_complexity)]
#![warn(missing_docs)]
#![warn(unreachable_pub)]

pub mod constraint;
pub mod constraint_weights;
Expand Down
3 changes: 3 additions & 0 deletions crates/solverforge-cvrp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ description = "CVRP domain helpers for SolverForge"

[dependencies]
solverforge-solver = { version = "=0.25.1", path = "../solverforge-solver" }

[lints.rust]
missing_docs = "warn"
2 changes: 0 additions & 2 deletions crates/solverforge-cvrp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//! the `VrpSolution` trait, and the stock helpers behind
//! `#[planning_list_variable(domain = "cvrp")]`.

#![warn(missing_docs)]

mod helpers;
mod meters;
mod problem_data;
Expand Down
3 changes: 3 additions & 0 deletions crates/solverforge-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ proc-macro2.workspace = true
[dev-dependencies]
solverforge = { path = "../solverforge" }
trybuild = "1.0.116"

[lints.rust]
missing_docs = "warn"
2 changes: 0 additions & 2 deletions crates/solverforge-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
//! `#[problem_fact]` and `#[solverforge_constraints]`; the generated code
//! refers to `::solverforge` paths.

#![warn(missing_docs)]

use proc_macro::TokenStream;

mod attr_parse;
Expand Down
2 changes: 2 additions & 0 deletions crates/solverforge-macros/tests/trybuild.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Compile-pass and compile-fail cases for the SolverForge procedural macros.

use std::path::Path;

#[test]
Expand Down
8 changes: 8 additions & 0 deletions crates/solverforge-scoring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ description = "Incremental constraint scoring for SolverForge"

[dependencies]
solverforge-core = { version = "=0.25.1", path = "../solverforge-core" }

[lints.rust]
unreachable_pub = "warn"
missing_docs = "warn"
unsafe_code = "forbid"

[lints.clippy]
type_complexity = "allow"
6 changes: 5 additions & 1 deletion crates/solverforge-scoring/WIREFRAME.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,10 @@ src/
│ ├── tri_stream.rs — TriConstraintStream, TriConstraintBuilder (via macro)
│ ├── quad_stream.rs — QuadConstraintStream, QuadConstraintBuilder (via macro)
│ ├── penta_stream.rs — PentaConstraintStream, PentaConstraintBuilder (via macro)
│ ├── chain.rs — Public `stream::chain` re-exports of Chain and ChainBuilder
│ ├── chain_stream.rs — Chain/ChainBuilder: arity-free fluent join continuation
│ ├── cross.rs — Public `stream::cross` re-exports of the cross-join streams and builders
│ ├── projected.rs — Public `stream::projected` re-exports of the projected streams and builders
│ ├── cross_penta_stream.rs — stream::cross::Penta and its Penta::join → Chain
│ ├── cross_penta_stream/scored.rs — PentaScored operator (tree plus authored filter)
│ ├── grouped_stream.rs — Re-exports
Expand Down Expand Up @@ -314,7 +317,8 @@ src/
│ ├── join_target.rs — JoinTarget/ToViewPlan dispatch for self-join, keyed cross-join, comparison, overlap, composed, and predicate cross-join
│ ├── key_extract.rs — KeyExtract trait, EntityKeyAdapter struct
│ ├── arity_stream_macros/
│ │ ├── mod.rs — impl_arity_stream! dispatcher macro
│ │ ├── mod.rs — Module declarations; re-exports impl_arity_stream!
│ │ ├── dispatch.rs — impl_arity_stream! dispatcher macro
│ │ ├── nary_stream.rs — Module declarations for arity stream macros
│ │ └── nary_stream/
│ │ ├── shared.rs — Shared arity stream macro helpers
Expand Down
4 changes: 0 additions & 4 deletions crates/solverforge-scoring/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
//! there is no `Box<dyn Trait>` on the scoring path.

// Zero-erasure architecture intentionally uses complex generic types
#![allow(clippy::type_complexity)]
#![warn(unreachable_pub)]
#![warn(missing_docs)]
#![forbid(unsafe_code)]

// Core modules
pub mod api;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! `impl_arity_stream!`: picks the per-arity stream macro for a tuple size.

/* Generates the constraint stream struct, builder struct, and common methods.

Doctests and unique methods (should be defined outside the macro
in the individual stream files.
*/
macro_rules! impl_arity_stream {
(bi, $stream:ident, $builder:ident) => {
impl_bi_arity_stream!($stream, $builder);
};
(tri, $stream:ident, $builder:ident) => {
impl_tri_arity_stream!($stream, $builder);
};
(quad, $stream:ident, $builder:ident) => {
impl_quad_arity_stream!($stream, $builder);
};
(penta, $stream:ident, $builder:ident) => {
impl_penta_arity_stream!($stream, $builder);
};
}

pub(crate) use impl_arity_stream;
23 changes: 3 additions & 20 deletions crates/solverforge-scoring/src/stream/arity_stream_macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,7 @@
#[macro_use]
mod nary_stream;

/* Generates the constraint stream struct, builder struct, and common methods.

Doctests and unique methods (should be defined outside the macro
in the individual stream files.
*/
macro_rules! impl_arity_stream {
(bi, $stream:ident, $builder:ident) => {
impl_bi_arity_stream!($stream, $builder);
};
(tri, $stream:ident, $builder:ident) => {
impl_tri_arity_stream!($stream, $builder);
};
(quad, $stream:ident, $builder:ident) => {
impl_quad_arity_stream!($stream, $builder);
};
(penta, $stream:ident, $builder:ident) => {
impl_penta_arity_stream!($stream, $builder);
};
}
#[macro_use]
mod dispatch;

pub(crate) use impl_arity_stream;
pub(crate) use dispatch::impl_arity_stream;
1 change: 1 addition & 0 deletions crates/solverforge-scoring/src/stream/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub use super::chain_stream::{Chain, ChainBuilder};
6 changes: 6 additions & 0 deletions crates/solverforge-scoring/src/stream/cross.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub use super::cross_bi_stream::{
Bi, Builder, ComplementedGrouped, ComplementedGroupedBuilder, Grouped, GroupedBuilder,
};
pub use super::cross_penta_stream::{Penta, PentaBuilder};
pub use super::cross_quad_stream::{Quad, QuadBuilder};
pub use super::cross_tri_stream::Tri;
21 changes: 3 additions & 18 deletions crates/solverforge-scoring/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,28 +114,13 @@ mod weighting_support;
mod tests;

/// Cross-collection join streams and their builders.
pub mod cross {
pub use super::cross_bi_stream::{
Bi, Builder, ComplementedGrouped, ComplementedGroupedBuilder, Grouped, GroupedBuilder,
};
pub use super::cross_penta_stream::{Penta, PentaBuilder};
pub use super::cross_quad_stream::{Quad, QuadBuilder};
pub use super::cross_tri_stream::Tri;
}
pub mod cross;

/// Chain stream and builder.
pub mod chain {
pub use super::chain_stream::{Chain, ChainBuilder};
}
pub mod chain;

/// Projected streams: rows emitted by a [`Projection`] instead of stored entities.
pub mod projected {
pub use super::projected_stream::{
Bi, BiBuilder, Builder, ComplementedGrouped, ComplementedGroupedBuilder, DirectedBi,
DirectedBiBuilder, Grouped, GroupedBuilder, JoinedSource, ProjectedJoinTarget, Projection,
ProjectionSink, RowCoordinate, RowOwner, Source, Stream,
};
}
pub mod projected;

pub use balance_stream::{BalanceConstraintBuilder, BalanceConstraintStream};
pub use bi_stream::{BiConstraintBuilder, BiConstraintStream};
Expand Down
5 changes: 5 additions & 0 deletions crates/solverforge-scoring/src/stream/projected.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub use super::projected_stream::{
Bi, BiBuilder, Builder, ComplementedGrouped, ComplementedGroupedBuilder, DirectedBi,
DirectedBiBuilder, Grouped, GroupedBuilder, JoinedSource, ProjectedJoinTarget, Projection,
ProjectionSink, RowCoordinate, RowOwner, Source, Stream,
};
3 changes: 3 additions & 0 deletions crates/solverforge-scoring/tests/group_by_joined.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! Grouping over self-joined streams: tri, quad and penta joins count
//! combinations and retract them incrementally.

use solverforge_core::score::SoftScore;
use solverforge_scoring::api::constraint_set::IncrementalConstraint;
use solverforge_scoring::stream::collector::count;
Expand Down
Loading
Loading