Coder Social home page Coder Social logo

nom-tutorial's People

Contributors

benkay86 avatar cvubrugier avatar dcroote avatar joelmon avatar paulgb avatar shika-blyat avatar tianyishi2001 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nom-tutorial's Issues

std::error::Error is now implemented

Hey, thank you for your efforts in creating this tutorial, much appreciated !

You may want to take into account that std::error::Error and std::fmt::Display traits were recently implemented for nom::Err and already made available in the subsequent releases.

Cheers!

updates for WSL support

Hi,

I found this tutorial while looking for nom tutorials. And Rust tutorials. This one seems to be the most up-to-date and well-written, and is essentially my first try at Rust. So thank you!

I had tried the tutorial on my WSL2 install (Ubuntu) on my Windows machine. But the parser fails at runtime, because of this weirdness in /proc/mounts (pasted verbatim):

C:\134 /mnt/c 9p rw,dirsync,noatime,aname=drvfs;path=C:\;uid=1000;gid=1000;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8 0 0

You may understand why this fails at first glance, but I didn't, so I needed to figure it out (which makes for an even better tutorial, IMO).

This is how I solved it.


Like our escaped_space, we need a new function to handle \134 (it's a backslash, which is totally not confusing at all). I think it should display as just C:\:

  fn windows_backslash(i: &str) -> nom::IResult<&str, &str> {
    nom::combinator::value("\\", nom::bytes::complete::tag("134"))(i)
  }

I added this to the tuple passed into nom::branch::alt():

      nom::branch::alt((
        escaped_backslash,
        windows_backslash,
        escaped_space
      )),

This seemed to work OK, until I had to parse the mount options, which failed because \; is invalid (see paste from /proc/mounts above). I added yet another parser, and added this to the nom::branch::alt call:

  fn windows_options_backslash(i: &str) -> nom::IResult<&str, &str> {
    nom::combinator::value("\\;", nom::bytes::complete::tag(";"))(i)
  }

and

      nom::branch::alt((
        escaped_backslash,
        windows_backslash,
        escaped_space,
        windows_options_backslash,
      )),

(I was not sure what to name either of these functions.)

At any rate, the tests I've written against the /proc/mounts entry pass (but I haven't had a chance to actually run it on my windows box yet). Here's the one for parse_line() with different data:

  #[test]
    fn test_parse_line_wsl2() {
      let mount3 = Mount {
        device: "C:\\".to_string(),
        mount_point: "/mnt/c".to_string(),
        file_system_type: "9p".to_string(),
        options: vec![
          "rw".to_string(),
          "dirsync".to_string(),
          "noatime".to_string(),
          "aname=drvfs;path=C:\\;uid=1000;gid=1000;symlinkroot=/mnt/".to_string(),
          "mmap".to_string(),
          "access=client".to_string(),
          "msize=65536".to_string(),
          "trans=fd".to_string(),
          "rfd=8".to_string(),
          "wfd=8".to_string(),
        ],
      };
      let (_, mount4) =
        parse_line("C:\\134 /mnt/c 9p rw,dirsync,noatime,aname=drvfs;path=C:\\;uid=1000;gid=1000;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8 0 0").unwrap();
      assert_eq!(mount3.device, mount4.device);
      assert_eq!(mount3.mount_point, mount4.mount_point);
      assert_eq!(mount3.file_system_type, mount4.file_system_type);
      assert_eq!(mount3.options, mount4.options);

Note: I found the following causes the my test to break, because it's not returning the correct type of Err result (it expects one from tag(), not char(), just like test_escaped_space()):

fn windows_options_backslash(i: &str) -> nom::IResult<&str, &str> {
  value("\\;", char(';'))(i)
}

The compiler didn't complain about this, which I found unusual, since it usually complains about everything. Assuming we're not deleting this parser, what would you have done? Update the unit test, write a new trait, etc.? I don't know what's idiomatic (yet).

I'd love if you could show how you may have tackled this problem. If you like, I can send a PR with changes for this environment, and we could also discuss the implementation that way. Or not!

Anyway, thanks again for this tutorial.

Remove fully qualified standard types

This issue is simply suggesting to remove the fully qualified types when dealing with things already imported by default.

This

#[derive(Clone, Default, Debug)]
pub struct Mount {
	pub device: std::string::String,
	pub mount_point: std::string::String,
	pub file_system_type: std::string::String,
	pub options: std::vec::Vec<std::string::String>,
}

could be written as this

#[derive(Clone, Default, Debug)]
pub struct Mount {
	pub device: String,
	pub mount_point: String,
	pub file_system_type: String,
	pub options: Vec<String>,
}

which is cleaner, more readable, better expresses the intent, and works out of the box in standard Rust.

References to removed ParseError in tutorial

The tutorial references the ParseError, which was removed in commit 34cd466
https://github.com/benkay86/nom-tutorial/blame/master/README.md#L551.

I was able to get it working with the following, but don't think it's a great solution as it's incompatible with the src version:

pub fn mounts() -> Result<(), Box<dyn Error>> {
	let file = std::fs::File::open("/proc/mounts")?;
	let buf_reader = std::io::BufReader::new(file);
	for line in buf_reader.lines() {
        match parsers::parse_line(&line?[..]) {
            Ok( (_, m) ) => {
				println!("{}", m);
			},
			Err(e) => return Err(e.to_owned().into())
        }
	}
	Ok(())
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.