#cursor #tree #immutability #zipper

the-zipper

The zipper is a data structure that allows you to traverse and modify a tree-like structure efficiently. It provides a way to navigate through the tree while keeping track of the context, enabling functional programming techniques.

4 releases

Uses new Rust 2024

new 0.1.3 Apr 15, 2025
0.1.2 Apr 7, 2025
0.1.1 Apr 7, 2025
0.1.0 Apr 7, 2025

#551 in Data structures

Download history 155/week @ 2025-04-01 176/week @ 2025-04-08

331 downloads per month

MIT license

27KB
671 lines

The Zipper

Crates.io

The Zipper is a Rust library designed to provide efficient and ergonomic utilities for working with data structures using the zipper pattern. This library simplifies navigation and modification of complex data structures while maintaining immutability.

HUET G. The Zipper. Journal of Functional Programming. 1997;7(5):549-554. doi:10.1017/S0956796897002864

Features

  • Easy-to-use API for zipper-based data manipulation.
  • Supports various data structures like trees and lists.
  • Lightweight and performant.
  • Code coverage is 100%.

Installation

Add the following to your Cargo.toml:

[dependencies]
the_zipper = "0.1.1"

Usage

use the_zipper::Location;

fn main() {
    let tree = Tree::Section(vec![Tree::Item("a"), Tree::Item("+"), Tree::Item("b")]);

    let location = Location::new(tree);

    let location = location.go_down().unwrap();
    assert_eq!(location.cursor, Tree::Item("a"));

    let location = location.go_right().unwrap();
    assert_eq!(location.cursor, Tree::Item("+"));

    let location = location.go_left().unwrap();
    assert_eq!(location.cursor, Tree::Item("a"));

    let location = location.insert_right(Tree::Item(".")).unwrap();
    assert_eq!(
        location,
        Location {
            cursor: Tree::Item("a"),
            path: Path::Node {
                left: vec![],
                right: vec![Tree::Item("."), Tree::Item("+"), Tree::Item("b")],
                path: Path::Node {
                    left: vec![],
                    right: vec![Tree::Section(vec![
                        Tree::Item("a"),
                        Tree::Item("+"),
                        Tree::Item("b")
                    ])],
                    path: Path::Top.into()
                }
                .into()
            }
            .into()
        }
        .into()
    );
}

F# Implementation

License

This project is licensed under the MIT License. See the LICENSE file for details.

No runtime deps