Crate dbase[][src]

dbase is rust library meant to read and write dBase / FoxPro files.

Theses files are nowadays generally only found in association with shapefiles.

Reading

The Reader is the struct that you’ll need to use in order to read the content of a dBase file.

Once you have access to the records, you will have to match against the real FieldValue

Examples

use dbase::FieldValue;
let records = dbase::read("tests/data/line.dbf")?;
for record in records {
    for (name, value) in record {
        println!("{} -> {:?}", name, value);
        match value {
            FieldValue::Character(Some(string)) => println!("Got string: {}", string),
            FieldValue::Numeric(value) => println!("Got numeric value of  {:?}", value),
            _ => {}
        }
    }
}

You can also create a Reader and iterate over the records.

let mut reader = dbase::Reader::from_path("tests/data/line.dbf")?;
for record_result in reader.iter_records() {
    let record = record_result?;
    for (name, value) in record {
        println!("name: {}, value: {:?}", name, value);
    }
}

Deserialisation

If you know what kind of data to expect from a particular file you can use implement the ReadbableRecord trait to “deserialize” the record into your custom struct:

use std::io::{Read, Seek};
struct StationRecord {
    name: String,
    marker_col: String,
    marker_sym: String,
    line: String,
}

impl dbase::ReadableRecord for StationRecord {
    fn read_using<T>(field_iterator: &mut dbase::FieldIterator<T>) -> Result<Self, dbase::FieldIOError>
         where T: Read + Seek{
        Ok(Self {
            name: field_iterator.read_next_field_as()?.value,
            marker_col: field_iterator.read_next_field_as()?.value,
            marker_sym: field_iterator.read_next_field_as()?.value,
            line: field_iterator.read_next_field_as()?.value,
        })
    }
}
let mut reader = dbase::Reader::from_path("tests/data/stations.dbf")?;
let stations = reader.read_as::<StationRecord>()?;

assert_eq!(stations[0].name, "Van Dorn Street");
assert_eq!(stations[0].marker_col, "#0000ff");
assert_eq!(stations[0].marker_sym, "rail-metro");
assert_eq!(stations[0].line, "blue");

If you use the serde optional feature and serde_derive crate you can have the ReadbableRecord impletemented for you

extern crate serde_derive;


use std::io::{Read, Seek};
use serde_derive::Deserialize;

#[derive(Deserialize)]
struct StationRecord {
    name: String,
    marker_col: String,
    marker_sym: String,
    line: String,
}

let mut reader = dbase::Reader::from_path("tests/data/stations.dbf")?;
let stations = reader.read_as::<StationRecord>()?;

assert_eq!(stations[0].name, "Van Dorn Street");
assert_eq!(stations[0].marker_col, "#0000ff");
assert_eq!(stations[0].marker_sym, "rail-metro");
assert_eq!(stations[0].line, "blue");

Writing

In order to get a TableWriter you will need to build it using its TableWriterBuilder to specify the fields that constitute a record.

As for reading, you can serialize structs into a dBase file, given that they match the declared fields in when building the TableWriterBuilder by implementing the WritableRecord.

Examples

let mut reader = dbase::Reader::from_path("tests/data/stations.dbf")?;
let mut stations = reader.read()?;

let mut writer = dbase::TableWriterBuilder::from_reader(reader)
    .build_with_file_dest("stations.dbf").unwrap();

stations[0].get_mut("line").and_then(|_old| Some("Red".to_string()));
writer.write_records(&stations)?;
use dbase::{TableWriterBuilder, FieldName, WritableRecord, FieldWriter, FieldIOError};
use std::convert::TryFrom;
use std::io::{Cursor, Write};

struct User {
    nick_name: String,
    age: f64
}

impl WritableRecord for User {
    fn write_using<'a, W: Write>(&self, field_writer: &mut FieldWriter<'a, W>) -> Result<(), FieldIOError> {
        field_writer.write_next_field_value(&self.nick_name)?;
        field_writer.write_next_field_value(&self.age)?;
        Ok(())
    }
}

let mut writer = TableWriterBuilder::new()
    .add_character_field(FieldName::try_from("Nick Name").unwrap(), 50)
    .add_numeric_field(FieldName::try_from("Age").unwrap(), 20, 10)
    .build_with_dest(Cursor::new(Vec::<u8>::new()));


let records = User{
    nick_name: "Yoshi".to_string(),
    age: 32.0,
};

writer.write_record(&records);

If you use the serde optional feature and serde_derive crate you can have the WritableRecord impletemented for you.

extern crate serde_derive;

use serde_derive::Serialize;

use dbase::{TableWriterBuilder, FieldName, WritableRecord, FieldWriter};
use std::convert::TryFrom;
use std::io::{Cursor, Write};

#[derive(Serialize)]
struct User {
    nick_name: String,
    age: f64
}

let writer = TableWriterBuilder::new()
    .add_character_field(FieldName::try_from("Nick Name").unwrap(), 50)
    .add_numeric_field(FieldName::try_from("Age").unwrap(), 20, 10)
    .build_with_dest(Cursor::new(Vec::<u8>::new()));


let records = vec![User{
    nick_name: "Yoshi".to_string(),
    age: 32.0,
}];

    writer.write_records(&records);

Macros

dbase_record

macro to define a struct that implements the ReadableRecord and WritableRecord

Structs

Date

dBase representation of date

DateTime

FoxBase representation of a DateTime

Error

The error type for this crate

FieldIOError
FieldInfo

Struct giving the info for a record field

FieldIterator

Iterator over the fields in a dBase record

FieldName

Wrapping struct to create a FieldName from a String.

FieldWriter

Struct that knows how to write a record

NamedValue

Simple struct to wrap together the value with the name of the field it belongs to

Reader

Struct with the handle to the source .dbf file Responsible for reading the content

Record

Type definition of a generic record. A .dbf file is composed of many records

RecordIterator

Iterator over records contained in the dBase

TableInfo

Structs containing the information allowing to create a new TableWriter which would write file with the same record structure as another dbase file.

TableWriter

Structs that writes dBase records to a destination

TableWriterBuilder

Builder to be used to create a TableWriter.

Time

FoxBase representation of a time

Enums

ErrorKind
FieldConversionError

Errors that can happen when trying to convert a FieldValue into a more concrete type

FieldValue

Enum where each variant stores the record value

Traits

ReadableRecord

Trait to be implemented by structs that represent records read from a dBase file.

WritableRecord

Trait to be implemented by struct that you want to be able to write to (serialize) a dBase file

Functions

read

One liner to read the content of a .dbf file