Search code examples
databaserustleveldb

Rust return leveldb Database instance


I want to use the leveldb database in Rust. Everything works fine if I have all the code in one function, but I want to split the code up and have different functions for creating an entry and reading from the db. The easiest method I thought of, was to return the database instance I created in create_database and then submit it as a parameter to the function. The Problem is that Rust doesn't allow me to use Database as a type.

This works:

use std::{env, fs};
use leveldb::database::Database;
use leveldb::iterator::Iterable;
use leveldb::kv::KV;
use leveldb::options::{Options, WriteOptions, ReadOptions};


pub fn create_database() {
    let mut dir = env::current_dir().unwrap();
    dir.push("demo");

    let path_buf = dir.clone();
    fs::create_dir_all(dir).unwrap();

    let path = path_buf.as_path();
    let mut options = Options::new();
    options.create_if_missing = true;

    // Create Database
    let database = match Database::open(path, options) {
        Ok(db) => {db},
        Err(e) => {panic!("Failed to open database: {:?}", e)}
    };

    // Read from database
    let read_opts = ReadOptions::new();
    let res = database.get(read_opts, 1);
    match res {
        Ok(data) => {
            assert!(data.is_some());
            assert_eq!(data, Some(vec![1]));
        }
        Err(e) => {panic!("Failed to read from database: {:?}", e)}
    };

    let read_opts = ReadOptions::new();
    let mut iter = database.iter(read_opts);
    let entry = iter.next();
    assert_eq!(
        entry,
        Some((1, vec![1]))
    );

    // Write to database
    let write_ops = WriteOptions::new();
    match database.put(write_ops, 1, &[1]) {
        Ok(_) => {()},
        Err(e) => {panic!("Failed to write to database: {:?}", e)}
    };
}

But this doesn't:

use std::{env, fs};
use leveldb::database::Database;
use leveldb::iterator::Iterable;
use leveldb::kv::KV;
use leveldb::options::{Options, WriteOptions, ReadOptions};


pub fn create_database() -> Database {
    let mut dir = env::current_dir().unwrap();
    dir.push("demo");

    let path_buf = dir.clone();
    fs::create_dir_all(dir).unwrap();

    let path = path_buf.as_path();
    let mut options = Options::new();
    options.create_if_missing = true;

    // Create Database
    let database = match Database::open(path, options) {
        Ok(db) => {db},
        Err(e) => {panic!("Failed to open database: {:?}", e)}
    };
    return database;
}

pub fn get(database: Database) {
    // Read from database
    let read_opts = ReadOptions::new();
    let res = database.get(read_opts, 1);
    match res {
        Ok(data) => {
            assert!(data.is_some());
            assert_eq!(data, Some(vec![1]));
        }
        Err(e) => {panic!("Failed to read from database: {:?}", e)}
    };

    let read_opts = ReadOptions::new();
    let mut iter = database.iter(read_opts);
    let entry = iter.next();
    assert_eq!(
        entry,
        Some((1, vec![1]))
    );
}

pub fn put(database: Database) {
    // Write to database
    let write_ops = WriteOptions::new();
    match database.put(write_ops, 1, &[1]) {
        Ok(_) => {()},
        Err(e) => {panic!("Failed to write to database: {:?}", e)}
    };
}

If I execute this program I get this error:

error[E0107]: wrong number of type arguments: expected 1, found 0
 --> src/db/db.rs:8:29
  |
8 | pub fn create_database() -> Database {
  |                             ^^^^^^^^ expected 1 type argument

error[E0107]: wrong number of type arguments: expected 1, found 0
  --> src/db/db.rs:27:22
   |
27 | pub fn get(database: Database) {
   |                      ^^^^^^^^ expected 1 type argument

error[E0107]: wrong number of type arguments: expected 1, found 0
  --> src/db/db.rs:48:22
   |
48 | pub fn put(database: Database) {
   |                      ^^^^^^^^ expected 1 type argument

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0107`.
error: could not compile `gcoin`

To learn more, run the command again with --verbose.

I have tried looking for examples to use this database but didn't find anything that matched. In the source code I found out that Database has a generic type, but couldn't find a way to fix my problem.


Solution

  • Solved! Thanks Locke and kmdreko