Search code examples
readlinerust

Interfacing readline into Rust


I try to do this tutorial in rust, so far I have a lot of problems interfacing the C library into Rust.

C equivalent code:

#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;
}

So far i got this:

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);
            }
        }
    }
}

Especifically, I'm having issues with rust_readline function, i don't understand very well what's doing inside.


Solution

  • Edit Cargo.toml, put this:

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

    Code corrected:

    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 :-) .