milibopp/carboxyl
{ "createdAt": "2015-01-17T12:18:04Z", "defaultBranch": "main", "description": "Functional Reactive Programming library for Rust", "fullName": "milibopp/carboxyl", "homepage": "", "language": "Rust", "name": "carboxyl", "pushedAt": "2025-01-28T04:45:20Z", "stargazersCount": 418, "topics": [], "updatedAt": "2025-08-10T17:01:03Z", "url": "https://github.com/milibopp/carboxyl"}Carboxyl is a library for functional reactive programming in Rust, a functional and composable approach to handle events in interactive applications. Read more [in the docs…][docs]
[docs] !: https://docs.rs/carboxyl/
Usage example
Section titled “Usage example”Here is a simple example of how you can use the primitives provided by Carboxyl. First of all, events can be sent into a sink. From a sink one can create a stream of events. Streams can also be filtered, mapped and merged. A signal is an abstraction of a value that may change over time. One can e.g. hold the last event from a stream in a signal.
extern crate carboxyl;
fn main() { let sink = carboxyl::Sink::new(); let stream = sink.stream(); let signal = stream.hold(3);
// The current value of the signal is initially 3 assert_eq!(signal.sample(), 3);
// When we fire an event, the signal get updated accordingly sink.send(5); assert_eq!(signal.sample(), 5);}One can also directly iterate over the stream instead of holding it in a signal:
extern crate carboxyl;
fn main() { let sink = carboxyl::Sink::new(); let stream = sink.stream();
let mut events = stream.events(); sink.send(4); assert_eq!(events.next(), Some(4));}Streams and signals can be combined using various primitives. We can map a stream to another stream using a function:
extern crate carboxyl;
fn main() { let sink = carboxyl::Sink::new(); let stream = sink.stream();
let squares = stream.map(|x| x * x).hold(0); sink.send(4); assert_eq!(squares.sample(), 16);}Or we can filter a stream to create a new one that only contains events that satisfy a certain predicate:
extern crate carboxyl;
fn main() { let sink = carboxyl::Sink::new(); let stream = sink.stream();
let negatives = stream.filter(|&x| x < 0).hold(0);
// This won't arrive at the signal. sink.send(4); assert_eq!(negatives.sample(), 0);
// But this will! sink.send(-3); assert_eq!(negatives.sample(), -3);}There are a couple of other primitives to compose streams and signals:
mergetwo streams of events of the same type.- Make a
snapshotof a signal, whenever a stream fires an event. lift!an ordinary function to a function on signals.switchbetween different signals using a signal containing a signal.
See the [documentation][docs] for details.
License
Section titled “License”Copyright 2014-2020 Carboxyl contributors.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.