match_deref

Crates.iomatch_deref
lib.rsmatch_deref
version
sourcesrc
created_at2022-07-28 21:47:15.37931
updated_at2024-12-28 19:43:40.271879
descriptionDeref patterns in "match" for stable Rust. Now you can match through Rc, String, etc
homepagehttps://sr.ht/~safinaskar/match_deref-rs
repositoryhttps://git.sr.ht/~safinaskar/match_deref-rs
max_upload_size
id634690
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Askar Safin (safinaskar)

documentation

README

Deref patterns in match for stable Rust. Now you can match through Rc, String, etc.

(Note: as on 2024-12-28 nightly has expiremental support for deref patterns, see end of this README for details.)

match_deref::match_deref!{...} is a procedural macro, which allows you to use deref patterns right now in stable Rust.

For example:

use std::rc::Rc;

enum Value {
    Nil,
    Cons(Rc<Value>, Rc<Value>),
    Symbol(String),
}

use Value::*;

fn main() {
    let v: &Value = todo!();
    match_deref::match_deref!{
        match v {
            Nil => todo!(),
            Cons(Deref @ Symbol(Deref @ "quote"), Deref @ Cons(x, Deref @ Nil)) => todo!(),
            _ => todo!(),
        }
    }
}

But there is a problem in my crate: all arms with Deref @ are ignored when compiler performs exhaustiveness checking. So sometimes you will need to add _ => unreachable!() to the end.

I. e. it is possible that your arms are exhaustive, but the compiler will not be able to check this. But it is not possible that you arms are not exhaustive and the compiler will falsely report them as exhaustive.

(I decided not to implement full exhaustiveness checking, because I hope that truly native support for deref patterns will be implemented in the rustc soon, so my work will be unneeded anyway. But if you want to implement similar macro with full exhaustiveness checking, go ahead, I can even link to your project here.)

The macro calls Deref::deref internally. Keep in mind that Deref::deref takes REFERENCE to smart pointer and returns REFERENCE to pointee. So this code will work: match &Nil { Deref @ x => ... }, but this will not: match Nil { Deref @ x => ... }.

Consider this code:

match_deref::match_deref!{
    match v {
        Symbol(Deref @ x) => some_code_here,
        _ => other_code_here,
    }
}

It will be desugared to something like this:

match v {
    Symbol(a0) if (if let x = Deref::deref(a0) { true } else { false }) => if let x = Deref::deref(a0) {
        some_code_here
    } else {
        panic!()
    },
    _ => other_code_here,
}

My macro is hygienic, i. e. everything will work even if you use variable named a0

As on 2024-12-28 nightly has expiremental support for deref patterns. This is how you can use it (without this crate):

#![feature(deref_patterns)]
#![feature(string_deref_patterns)]
#![allow(incomplete_features)]

use std::rc::Rc;

enum Value {
    Nil,
    Cons(Rc<Value>, Rc<Value>),
    Symbol(String),
}

use Value::*;

fn main() {
    let v: Value = todo!();
    match v {
        Nil => todo!(),
        Cons(deref!(Symbol("quote")), deref!(Cons(x, deref!(Nil)))) => todo!(),
        _ => todo!(),
    }
}

You don't need to be registered on SourceHut to create bug report.

If you think that this software is not needed or existing software already subsumes its functionality, please, tell me that, I will not be offended.

Commit count: 0

cargo fmt