将readline连接到Rust

时间:2014-10-05 18:10:34

标签: readline rust

我尝试在生锈中执行this tutorial,到目前为止,我在将C库连接到Rust时遇到了很多问题。

C等效代码:

#include <stdio.h>
#include <stdlib.h>

#include <editline/readline.h>
#include <editline/history.h>

int main(int argc, char** argv) {

  /* Print Version and Exit Information */
  puts("Lispy Version 0.0.0.0.1");
  puts("Press Ctrl+c to Exit\n");

  /* In a never ending loop */
  while (1) {

    /* Output our prompt and get input */
    char* input = readline("lispy> ");

    /* Add input to history */
    add_history(input);

    /* Echo input back to user */    
    printf("No you're a %s\n", input);

    /* Free retrived input */
    free(input);

  }

  return 0;
}

到目前为止我得到了这个:

extern crate libc;

use std::c_str;

#[link(name = "readline")]
extern {
    fn readline (p: *const libc::c_char) -> *const libc::c_char;
}

fn rust_readline (prompt: &str) -> Option<Box<str>> {
    let cprmt = prompt.to_c_str();
    cprmt.with_ref(|c_buf| {
        unsafe {
            let ret = c_str::CString::new (readline (c_buf), true);
            ret.as_str().map(|ret| ret.to_owned())
        }
    })
}

fn main() {
    println!("Lispy Version 0.0.1");
    println!("Press Ctrl+c to Exit.\n");

// I want to have "history" in Linux of this:
//  
//  loop {
//      print!("lispy> ");
//      let input = io::stdin().read_line().unwrap();
//      print!("No you're a {}", input);
//  }

    loop {
        let val = rust_readline ("lispy> ");
        match val {
            None => { break }
            _ => {
                let input = val.unwrap();
                println!("No you're a {}", input);
            }
        }
    }
}

特别是,我有关于rust_readline功能的问题,我不太清楚他们在做什么。

2 个答案:

答案 0 :(得分:5)

编辑Cargo.toml,把它放在:

[dependencies.readline]

git = "https://github.com/shaleh/rust-readline"

代码更正:

extern crate readline;

fn main() {
    println!("Lispy Version 0.0.1");
    println!("Press Ctrl+c to Exit.\n");

    loop {
        let input = readline::readline("lispy> ").unwrap();
        readline::add_history(input.as_str());
        println!("No you're a {}", input);
    }
}

Happy Lisping :-)。

答案 1 :(得分:0)

有趣的是,我发现这个问题读的是同一本书,但我的搜索查询中没有包含任何特定于本书的信息。

现在有一个板条箱。 Facon的解决方案对我有用,但是使用该库,提示字符串始终打印为垃圾,因此我寻找了另一个板条箱,发现其中一个工作良好。这是一个更新的示例:

cargo.toml

[dependencies]
# https://crates.io/crates/rustyline
rustyline = "3.0.0"

main.rs

extern crate rustyline;

use rustyline::error::ReadlineError;
use rustyline::Editor;

const HISTORY_FILENAME: &str = "history.txt";

fn main() {
    println!("Lispy Version 0.0.1");
    println!("Press Ctrl+c to Exit.\n");

    // We create an editor for the readline history.
    let mut readline_editor = Editor::<()>::new();
    // And then load the history, if it exists.
    if readline_editor.load_history(HISTORY_FILENAME).is_err() {
        println!("No previous history.");
    }


    loop {
        // We read some input from CLI.
        let readline = readline_editor.readline("LISPY>> ");
        // The reading of the input could fail, if a user uses special
        // key combinations. So we match against the readline Result
        // type. Result can either be some `Ok` or an some `Err`.
        match readline {
            Ok(line) => {
                readline_editor.add_history_entry(line.as_ref());
                println!("No, you are {}", line);
            },
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break
            },
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);
                break
            }
        }
        readline_editor.save_history(HISTORY_FILENAME).expect("Could not save to readline history.");
    }
}