Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Capture A Match That Is Not Followed By A Tag In Rust's nom

The goal with this one is to looks for boolean attributes in Neopolitan that include a colon in them. This is used for things like URLs.

The mechanic is that if there's a colon without a space it's treated as an attribute. If there is a space it throws an error (becuase it's a key value pair at that point)

Code

//! ```cargo
//! [dependencies]
//! nom = "7.1.3"
//! ```

use nom::bytes::complete::take_until;
use nom::error::Error;
use nom::error::ErrorKind;
use nom::Err;
use nom::IResult;
use nom::bytes::complete::is_not;
use nom::bytes::complete::tag;
use nom::combinator::not;
use nom::combinator::opt;

fn main() {
  assert_eq!(
    Ok((">", "alfa:bravo".to_string())), 
    bool_with_colon("alfa:bravo>")
  );

  assert_eq!(
    Err(Err::Error(Error::new(": echo", ErrorKind::Not))),
    bool_with_colon("delta: echo>")
  );

  println!("done");
}

fn bool_with_colon(source: &str) -> IResult<&str, String> {
  let (source, result) = is_not(">")(source)?;
  let (verify, _) = opt(take_until(":"))(result)?;
  let (_, _) = not(tag(": "))(verify)?;
  Ok((source, result.to_string()))
}

Results

done