Skip to content

Commit 1ee9455

Browse files
committed
docs(fzn-rs): Comments and naming of types
1 parent 8faa08a commit 1ee9455

File tree

3 files changed

+40
-41
lines changed

3 files changed

+40
-41
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["./pumpkin-solver", "./drcp-format", "./pumpkin-solver-py", "./pumpkin-macros", "./drcp-debugger", "./pumpkin-crates/*", "./fzn_rs", "./fzn_rs_derive"]
2+
members = ["./pumpkin-solver", "./drcp-format", "./pumpkin-solver-py", "./pumpkin-macros", "./drcp-debugger", "./pumpkin-crates/*", "./fzn-rs", "./fzn-rs-derive"]
33
default-members = ["./pumpkin-solver", "./drcp-format", "./pumpkin-solver-py", "./pumpkin-macros", "./pumpkin-crates/*"]
44
resolver = "2"
55

fzn-rs/src/lib.rs

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,17 @@
11
//! # fzn-rs
22
//!
3-
//! `fzn-rs` is a crate that allows for easy parsing of FlatZinc instances in Rust.
4-
//!
5-
//! ## Comparison to other FlatZinc crates
6-
//! There are two well-known crates for parsing FlatZinc files:
7-
//! - [flatzinc](https://docs.rs/flatzinc), for parsing the original `fzn` format,
8-
//! - and [flatzinc-serde](https://docs.rs/flatzinc-serde), for parsing `fzn.json`.
9-
//!
10-
//! The goal of this crate is to be able to parse both the original `fzn` format, as well as the
11-
//! newer `fzn.json` format. Additionally, there is a derive macro that allows for strongly-typed
12-
//! constraints as they are supported by your application. Finally, our aim is to improve the error
13-
//! messages that are encountered when parsing invalid FlatZinc files.
14-
//!
15-
//! ## Typed Instance
16-
//! The main type exposed by the crate is [`TypedInstance`], which is a fully typed representation
17-
//! of a FlatZinc model.
3+
//! `fzn-rs` is a crate that allows for easy parsing of FlatZinc instances in Rust. It facilitates
4+
//! type-driven parsing of a FlatZinc file using derive macros.
185
//!
6+
//! ## Example
197
//! ```
20-
//! use fzn_rs::TypedInstance;
21-
//!
22-
//! enum Constraints {
23-
//! // ...
24-
//! }
25-
//!
26-
//! type Instance = TypedInstance<i32, Constraints>;
27-
//! ```
28-
//!
29-
//! ## Derive Macro
30-
//! When parsing a FlatZinc file, the result is an [`ast::Ast`]. That type describes any valid
31-
//! FlatZinc file. However, when consuming FlatZinc, typically you need to process that AST
32-
//! further. For example, to support the [`int_lin_le`][1] constraint, you have to validate that the
33-
//! [`ast::Constraint`] has three arguments, and that each of the arguments has the correct type.
34-
//!
35-
//! When using this crate with the `derive` feature, you can instead do the following:
36-
//! ```rust
378
//! use fzn_rs::ArrayExpr;
389
//! use fzn_rs::FlatZincConstraint;
10+
//! use fzn_rs::TypedInstance;
3911
//! use fzn_rs::VariableExpr;
4012
//!
13+
//! /// The FlatZincConstraint derive macro enables the parsing of a strongly typed constraint
14+
//! /// based on the FlatZinc Ast.
4115
//! #[derive(FlatZincConstraint)]
4216
//! pub enum MyConstraints {
4317
//! /// The variant name is converted to snake_case to serve as the constraint identifier by
@@ -69,9 +43,27 @@
6943
//! b: VariableExpr<i64>,
7044
//! c: VariableExpr<i64>,
7145
//! }
46+
//!
47+
//! /// The `TypedInstance` is parameterized by the constraint type, as well as any annotations you
48+
//! /// may need to parse.
49+
//! type MyInstance = TypedInstance<i64, MyConstraints>;
50+
//!
51+
//! fn parse_flatzinc(source: &str) -> MyInstance {
52+
//! // First, the source string is parsed into a structured representation.
53+
//! //
54+
//! // Note: the `fzn_rs::fzn` module is only available with the `fzn` feature enabled.
55+
//! let ast = fzn_rs::fzn::parse(source).expect("source is valid flatzinc");
56+
//!
57+
//! // Then, the strongly-typed instance is created from the AST
58+
//! MyInstance::from_ast(ast).expect("type-checking passes")
59+
//! }
7260
//! ```
73-
//! The macro automatically implements [`FlatZincConstraint`] and will handle the parsing
74-
//! of arguments for you.
61+
//!
62+
//! ## Derive Macros
63+
//! When parsing a FlatZinc file, the result is an [`ast::Ast`]. That type describes any valid
64+
//! FlatZinc file. However, when consuming FlatZinc, typically you need to process that AST
65+
//! further. For example, to support the [`int_lin_le`][1] constraint, you have to validate that the
66+
//! [`ast::Constraint`] has three arguments, and that each of the arguments has the correct type.
7567
//!
7668
//! Similar to typed constraints, the derive macro for [`FlatZincAnnotation`] allows for easy
7769
//! parsing of annotations:
@@ -101,6 +93,16 @@
10193
//! annotation whose name does not match one of the variants in the enum, then the annotation is
10294
//! simply ignored.
10395
//!
96+
//! ## Comparison to other FlatZinc crates
97+
//! There are two well-known crates for parsing FlatZinc files:
98+
//! - [flatzinc](https://docs.rs/flatzinc), for parsing the original `fzn` format,
99+
//! - and [flatzinc-serde](https://docs.rs/flatzinc-serde), for parsing `fzn.json`.
100+
//!
101+
//! These crates produce what we call the [`ast::Ast`] in this crate, although the concrete types
102+
//! can be different. `fzn-rs` builds the strong typing of constraints and annotations on-top of
103+
//! a unified AST for both file formats. Finally, our aim is to improve the error messages that
104+
//! are encountered when parsing invalid FlatZinc files.
105+
//!
104106
//! [1]: https://docs.minizinc.dev/en/stable/lib-flatzinc-int.html#int-lin-le
105107
106108
mod error;

fzn-rs/src/typed/instance.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ pub struct TypedInstance<
3838
pub constraints: Vec<AnnotatedConstraint<Constraint, ConstraintAnnotations>>,
3939

4040
/// The solve item indicating how to solve the model.
41-
pub solve: Solve<Int, SolveAnnotations>,
41+
pub solve: SolveItem<Int, SolveAnnotations>,
4242
}
4343

4444
/// Specifies how to solve a [`TypedInstance`].
4545
///
4646
/// This is generic over the integer type.
4747
#[derive(Clone, Debug, PartialEq, Eq)]
48-
pub struct Solve<Int, Ann> {
48+
pub struct SolveItem<Int, Ann> {
4949
pub method: ast::Node<Method<Int>>,
5050
pub annotations: Vec<ast::Node<Ann>>,
5151
}
@@ -95,9 +95,6 @@ where
9595
///
9696
/// This parses the constraints and annotations, and can fail e.g. if the number or type of
9797
/// arguments do not match what is expected in the parser.
98-
///
99-
/// This does _not_ type-check the variables. I.e., if a constraint takes a `var int`, but
100-
/// is provided with an identifier of a `var bool`, then this function will gladly accept that.
10198
pub fn from_ast(ast: ast::Ast) -> Result<Self, InstanceError> {
10299
let variables = ast
103100
.variables
@@ -145,7 +142,7 @@ where
145142
})
146143
.collect::<Result<_, _>>()?;
147144

148-
let solve = Solve {
145+
let solve = SolveItem {
149146
method: match ast.solve.method.node {
150147
ast::Method::Satisfy => ast::Node {
151148
node: Method::Satisfy,

0 commit comments

Comments
 (0)