10 releases (5 stable)

2.0.2 Mar 30, 2026
2.0.1 Aug 5, 2025
2.0.0 Jul 11, 2024
1.0.1 Jan 18, 2022
0.1.0-rc2 Oct 23, 2021

#1983 in Procedural macros

Download history 32898/week @ 2025-12-28 108010/week @ 2026-01-04 117887/week @ 2026-01-11 114726/week @ 2026-01-18 110451/week @ 2026-01-25 131112/week @ 2026-02-01 178808/week @ 2026-02-08 154346/week @ 2026-02-15 160567/week @ 2026-02-22 166762/week @ 2026-03-01 173652/week @ 2026-03-08 170578/week @ 2026-03-15 203358/week @ 2026-03-22 174301/week @ 2026-03-29 191214/week @ 2026-04-05 227862/week @ 2026-04-12

804,175 downloads per month
Used in 123 crates (via ext-trait)

Zlib OR MIT OR Apache-2.0

10KB
227 lines

::ext-trait

Annotation to easily define ad-hoc / one-shot extension traits.

Repository Latest version Documentation MSRV unsafe forbidden License CI

Examples

  • Also

    #[macro_use]
    extern crate ext_trait;
    
    #[extension(trait Also)]
    impl<T> T {
        fn also (mut self, f: impl FnOnce(&mut Self))
          -> Self
        {
            f(&mut self);
            self
        }
    }
    
    fn main ()
    {
        use ::std::{collections::HashMap, ops::Not};
    
        let /* immut */ map = HashMap::with_capacity(2).also(|m| {
            m.insert("foo", 42);
            m.insert("bar", 27);
        });
        assert!(map.contains_key("foo"));
        assert!(map.contains_key("bar"));
        assert!(map.contains_key("baz").not());
    }
    
  • WithPath

    #[macro_use]
    extern crate ext_trait;
    
    use ::std::{error::Error, path::{Path, PathBuf}};
    
    #[extension(trait WithPath)]
    impl PathBuf {
        fn with (mut self, segment: impl AsRef<Path>)
          -> PathBuf
        {
            self.push(segment);
            self
        }
    }
    
    fn main ()
      -> Result<(), Box<dyn Error>>
    {
        let some_dir = PathBuf::from(::std::env::var("MY_LIB_SOME_DIR")?);
        // Contrary to chaining `.join()`, this reuses the memory!
        let some_subdir = some_dir.with("some").with("sub").with("dir");
        //
        Ok(())
    }
    
  • Context

    #[macro_use]
    extern crate ext_trait;
    
    use ::std::{error::Error, fmt::Display};
    
    #[extension(trait Context)]
    impl<Ok, Err : Display> Result<Ok, Err> {
        fn context (self, prefix: impl Display)
          -> Result<Ok, String>
        {
            self.map_err(|err| format!("{}: {}", prefix, err))
        }
    }
    
    fn main ()
      -> Result<(), Box<dyn Error>>
    {
        let file_contents =
            ::std::fs::read_to_string("some/file")
                .context("Error when opening some/file")?
        ;
        //
        Ok(())
    }
    

Similar to https://docs.rs/extension-trait, but for the following:

Features

  • Supports generics (see Context)

  • search/grep 'trait TraitName'-friendly!

Dependencies

~115–480KB
~11K SLoC