Coder Social home page Coder Social logo

rust-si's Introduction

Build Status Latest Version

You can use either the read! macro to read a single value and return it, or the scan! macro to read one or more values into variables. Both macros can also read from a file or from memory. The read! macro can take any type that implements Iterator<Item=u8> as an optional third argument, and the scan! macro's arguments can be prefixed with iter => where iter implements Iterator<Item=u8>.

Examples

scan! macro

use text_io::scan;

// reading from a string source
let i: i32;
scan!("<b>12</b>".bytes() => "<b>{}</b>", i);
assert_eq!(i, 12);

// reading multiple values from stdio
let a: i32;
let b: &mut u8 = &mut 5;
scan!("{}, {}", a, *b);

read! macro

use text_io::read;

// read until a whitespace and try to convert what was read into an i32
let i: i32 = read!();

// read until a whitespace (but not including it)
let word: String = read!(); // same as read!("{}")

// read until a newline (but not including it)
let line: String = read!("{}\n");

// expect the input "<b><i>" or panic
// read until the next "<" and return that.
// expect the input "/i></b>"
let stuff: String = read!("<b><i>{}</i></b>");

// reading from files
use std::io::Read;
let mut file = std::fs::File::open("tests/answer.txt").unwrap().bytes().map(|ch| ch.unwrap());
let val: i32 = read!("The answer is {}!!!11einself\n", file);

// reading from strings
let val: i32 = read!("Number: {}", "Number: 99".bytes());

rust-si's People

Contributors

brenomfviana avatar chrisxue815 avatar endle avatar frececroka avatar lireer avatar muhammadannaqeeb avatar oli-obk avatar qryxip avatar quadfault avatar quinn1876 avatar radsammyt avatar ryman avatar tamird 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

rust-si's Issues

Non-panicking mode

Can there be a macro that returns some Err instead of panicking?

fn handle_input(x: String) -> Result<i64, ()> {
    Ok(scan!(x, "MyValue(id={:x})"))
}

Using scan!() to read multiple values from a string source

I'm trying to parse multiple values from a string with scan!() in Rust 1.8, but have run into trouble. This is more likely a result of my n00b status with Rust than a problem with scan!.

Calling scan!() on a string in a single-file project works fine, just as the examples show.

However, when I move the use of scan!() out to another .rs file imported into the first, the project ceases to build.

mock@MockAir12 ~/P/P/scan_test> cargo build
   Compiling scan_test v0.1.0 (file:///Users/mock/Projects/Personal/scan_test)
<text_io macros>:18:19: 18:40 error: failed to resolve. Use of undeclared type or module `std::str` [E0433]
<text_io macros>:18 } ; let s = match std:: str:: from_utf8 ( & s ) {
                                      ^~~~~~~~~~~~~~~~~~~~~
src/parser.rs:4:5: 4:42 note: in this expansion of scan! (defined in <text_io macros>)
<text_io macros>:18:19: 18:40 help: run `rustc --explain E0433` to see a detailed explanation

I've thrown together some example code at https://github.com/alexmbird/scan_test.

Flush before read

read! macro doesn't work properly with print!.

This works for me

macro_rules! readf {
	($($arg:tt)*) => {{
		use std::io::Write;
		std::io::stdout().flush().unwrap();
		read!($($arg)*)
	}};
}

...

print!("Xn = ");
let xn: f64 = readf!();

Output:

Xn = 0.5

I think read! should flush stdout before reading.

Scan macro doesn't capture whitespace into strings

    let data = String::from("1-5 w:dsjvly wge");
    let min: i32;
    let max: i32;
    let c: char;
    let pw: String;
    scan!(data.bytes() => "{}-{} {}:{}", min, max, c, pw);
    dbg!(pw);

Here, pw returns dsjvly only, skipping wge. How should one get around this so the complete string gets captured?

Int parsing doesn't work on windows?

This code crashes with this error:

let Count: usize = read!("{}\n");

thread 'main' panicked at src\main.rs:44:24:
called 'Result::unwrap()' on an 'Err' value: Parse("1\r", "__try_read_var__")

I don't submit issues very often, so please tell me if I'm doing anything wrong

Consider adding read_line!

read!("{}\n") works on Windows, but the resulting string still has a nasty \r on the end.

It would be nice to have a read_line! that stops on either on \r or \n.

Read on other type of string

This is an interesting crate, but why limit it to the stdin ? I was interested to use it on string. An why not files ?

Issue with read! & serde_json::Result

I'm running into an issue when using serde_json's Result in the same program as text_io's read!() macro.

Here's an example:

#[macro_use] extern crate text_io;
use std::io;
use std::io::Write;

use serde::{Serialize, Deserialize};
use serde_json::{ Result, Value};



fn main() {
    print!("Enter name: ");
    std::io::stdout().flush().unwrap();
    let name :String = read!();
    println!("NAME: {}", name);
}

The compiler error is:

   |
14 |     let name :String = read!();
   |                        ^^^^^^^ the trait `std::convert::From<text_io::Error>` is not implemented for `serde_json::error::Error`


Travis CI stops working for this project

Since June 15th, 2021, the building on travis-ci.org is ceased. Please use travis-ci.com from now on.

        Travis CI - Test and Deploy Your Code with Confidence is in read-only mode. The historical data can be downloaded to external file storage.

The last successful build for rust_si was in October 2020 https://travis-ci.org/github/oli-obk/rust-si/builds

If anyone create a PR, or we have a new commit, we won't have CI results.

How about

  1. Migrate to travis-ci.com Or
  2. Migrate to Github Actions

several whitespaces at a stretch

panicked with
thread '

' panicked at 'called Result::unwrap() on an Err value: ParseFloatError { kind: Empty }', src/libcore/result.rs:736
if more than 1 whitespace after value in parsed string (for example 2 spaces or space + Enter)

read! is blocking in debug build but non blocking in release

I have the following piece of code:

loop {
    println!("Type 'exit' to terminate the program:");
    let input: String = read!("{}");
}

If I execute my program with cargo run (debug) everything is fine, the call to read! is blocking.
If I execute cargo build --release | target/build/myprog the loop prints the text over and over again.

Is there a way to avoid breaking when entering a wrong input type?

Hey, I just started using this crate and I was wondering if there's any way to avoid breaking an app when entering the wrong input type for a read() variable, for example:

    let number: i32 = read!();

This would break if I entered anything that's not i32 for example entering the word "car".

Is there any way of using for example exceptions here? I'm relatively new to Rust and I can't think of a good fix for this.

Thanks in advance! :)

`clippy::try_err` is triggered

use text_io::{read, try_read, try_scan};

fn main() {
    let _: i32 = read!();
}
$ cargo clippy --bin r
    Checking binary v0.0.0 (/home/ryo/src/competitive/rs/binary)
warning: returning an `Err(_)` with the `?` operator
 --> src/bin/r.rs:4:18
  |
4 |     let _: i32 = read!();
  |                  ^^^^^^^
  |
  = note: `#[warn(clippy::try_err)]` on by default
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#try_err
  = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
$ cargo +nightly expand --bin r
    Checking binary v0.0.0 (/home/ryo/src/competitive/rs/binary)
    Finished check [unoptimized + debuginfo] target(s) in 0.16s

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
use text_io::{read, try_read, try_scan};
fn main() {
    let _: i32 = {
        (|| -> Result<_, ::text_io::Error> {
            let __try_read_var__;
            use ::std::io::Read;
            {
                {
                    use ::text_io::{match_next, parse_capture, Error};
                    let pattern: &'static str = "{}";
                    let stdin: &mut Iterator<Item = u8> =
                        &mut (::std::io::stdin().bytes().map(|c| c.unwrap()));
                    let mut pattern = pattern.bytes();
                    __try_read_var__ = loop {
                        match { (pattern.next().ok_or(Error::MissingMatch))? } {
                            b'{' => match { (pattern.next().ok_or(Error::MissingClosingBrace))? } {
                                b'{' => (match_next(b'{', stdin))?,
                                b'}' => {
                                    break {
                                        (parse_capture("__try_read_var__", pattern.next(), stdin))?
                                    }
                                }
                                _ => return { (Err(Error::MissingClosingBrace))? },
                            },
                            c => (match_next(c, stdin))?,
                        }
                    };
                    for c in pattern {
                        {
                            (match_next(c, stdin))?
                        }
                    }
                    ::core::fmt::Arguments::new_v1(
                        &[""],
                        &match (&__try_read_var__,) {
                            (arg0,) => [::core::fmt::ArgumentV1::new(
                                arg0,
                                ::core::fmt::Display::fmt,
                            )],
                        },
                    );
                }
            };
            ::core::fmt::Arguments::new_v1(
                &[""],
                &match (&__try_read_var__,) {
                    (arg0,) => [::core::fmt::ArgumentV1::new(
                        arg0,
                        ::core::fmt::Display::fmt,
                    )],
                },
            );
            Ok(__try_read_var__)
        })()
    }
    .unwrap();
}

Support 2018 style macro import

use text_io::scan;

fn main() {
    let x: u32;
    scan!("{}", x);
}

Expected behavior: compiles.
Current behavior:

error: cannot find macro `try_scan!` in this scope
 --> src/main.rs:5:5
  |
5 |     scan!("{}", x);
  |     ^^^^^^^^^^^^^^^
  |
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

No documentation

Or I can't find it.

Is read! the only macro? How do I use existing string without reading from input?

The license is non-free

Greetings!

I see that you are using a custom license that includes the restriction "The Software may not be used in
any system whose intent is harm any person's privacy, body or mind." I am not a laywer, but this seems similar to the JSON license's clause that the software must be used for good and not evil. You can use a web search to find analysis on why that license is considered non-free.

Though the goal does seem good, one of the problems with the text is that it does not define what "harm" is (similar to how "evil" and "good" are not easy to define in the JSON license).

I recommend relicensing under an OSI approved license.

try_scan action that returns None on error

It would be very convenient to have try_scan!(@impl or_none, ...) to use in functions that return Option.

The current solutions only provide unwrapping and returning Result.

text_io 0.1.10 and 0.1.12 fails in older code

I use 0.1.10 in a system, where edition 2021 is not available. However, if I download the dependencies, it tries to download 0.1.12, but it would like to use edition 2021. So I cannot compile my older code in production. This is a serious issue, now.

in my Cargo.toml:

...
edition = "2018"

[dependencies]
text_io = "0.1.10"
...

But this is what I get when I try to use it:

error: failed to download `text_io v0.1.12`

Caused by:
  unable to get packages from source

Caused by:
  failed to parse manifest at `/home/fercsi/.cargo/registry/src/github.com-1ecc6299db9ec823/text_io-0.1.12/Cargo.toml`

Caused by:
  failed to parse the `edition` key

Caused by:
  this version of Cargo is older than the `2021` edition, and only supports `2015` and `2018` editions.

Hide implementation details from try_scan!

The following two macro variants seem to be more of an implementation detail than a part of the public API

(@question_mark: $($e:tt)+) => { ... };
(@unwrap: $($e:tt)+) => { ... };

When I first encountered it, I puzzled over them a good while to figure out what library users where supposed to achieve with this. Only after a while did I realize that this was an implementation detail for the bottom-most macro rule.

To avoid this confusion and clear up the docs, these two macro rules could be moved into a separate, private macro

BUG | `Read` reimported here - scan macro

When I try to compile:
fn main() {
let a: u8;
let b: u8;
scan!("{}", a);
scan!("{}", b);
}
It says:
error[E0252]: the name Read is defined multiple times
--> src\main.rs:46:5
|
46 | scan!("{}", a);
| ^^^^^^^^^^^^^^^ Read reimported here
47 | scan!("{}", b);
| --------------- previous import of the trait Read here
|
= note: Read must be defined only once in the type namespace of this block
= note: this error originates in the macro scan (in Nightly builds, run with -Z macro-backtrace for more info)

I've found out this as a bug, can you fix it please?

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.