3 releases

0.1.2 May 19, 2024
0.1.1 Mar 24, 2024
0.1.0 Jan 30, 2024

#256 in Math

Download history 41/week @ 2024-03-10 13/week @ 2024-03-17 135/week @ 2024-03-24 42/week @ 2024-03-31 1/week @ 2024-04-07 199/week @ 2024-05-19 1/week @ 2024-05-26

215 downloads per month


237 lines

floco 🛟   Build Status Codecov Badge Apache Badge MIT Badge

Floco validates floats against user-defined constraints.

Quick Start

use floco::{Floco, Constrained};

// We want to represent a value as f64, but we don't want to allow:
//      - values below 5.0f64
//      - values above 7.2f64

// We define an empty struct.
// This won't contain data, but will contain validation criteria in its impl.
struct Foo;

// The Constrained trait defines the above constraints, an error type, and a default value.
impl Constrained<f64> for Foo {

    type Error = &'static str;

    fn is_valid(value: f64) -> bool {
        value >= 5.0f64 && value <= 7.2f64

    fn emit_error(_value: f64) -> Self::Error {
        "yikes this is a bad foo"

    // Optionally, you can set a custom default.
    // Floco::<F, YourType>::Default will respect the default value impl for YourType.
    fn get_default() -> f64 {

// Now we can use Foo to constrain a Floco
let this_will_be_ok = Floco::<f64, Foo>::try_new(6.8);
let this_will_be_err = Floco::<f64, Foo>::try_new(4.2);


This crate provides a struct that wraps a floating-point number alongside a PhantomData marker type. The marker type defines arbitrary validation conditions for the inner float. These validation conditions are invoked during construction, conversion, and deserialization.

The marker type also provides an Error type and an optional default value (defaults to zero).

Floco is no_std compatible by default, but has optional support for the standard library behind a feature flag. This doesn't add any functionality, just changes math ops from libm to std and changes the errors from thiserror-core to thiserror. Floco should compile on stable if std is enabled, but will require the error_in_core feature for no_std builds.

Floco is compatible with any type that implements the float trait from the num_traits crate. TryFrom conversions are implemented from f32 and f64 for convenience.


  • At some point I intend to implement the ops traits on the Floco struct.
  • At some point I intend to add a macro to reduce the newtype boilerplate.
  • I want to create a similar struct that also contains generic uom dimensions, but might just put that in a separate crate.
  • Not sure what to do with the Copy trait. Need to think that through.
  • prae uses a macro to create distinct types rather than making a single type generic across arbitrary marker impls. Prae is incompatible with no_std.
  • tightness is a predecessor to prae.
  • typed_floats provides 12 useful pre-made restricted float types. See the useful "Similar crates" section at the end of the TypedFloats readme.

Inspired By


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~34K SLoC