#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct AvroField {
pub name: String,
pub field_type: String,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct AvroSchema {
pub name: String,
pub namespace: String,
pub fields: Vec<AvroField>,
}
#[allow(dead_code)]
#[derive(Debug, Clone, Default)]
pub struct AvroRecord {
pub values: Vec<(String, String)>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct AvroExport {
pub schema: AvroSchema,
pub records: Vec<AvroRecord>,
}
#[allow(dead_code)]
pub fn new_avro_schema(name: &str, namespace: &str) -> AvroSchema {
AvroSchema {
name: name.to_string(),
namespace: namespace.to_string(),
fields: Vec::new(),
}
}
#[allow(dead_code)]
pub fn add_avro_field(schema: &mut AvroSchema, name: &str, field_type: &str) {
schema.fields.push(AvroField {
name: name.to_string(),
field_type: field_type.to_string(),
});
}
#[allow(dead_code)]
pub fn new_avro_export(schema: AvroSchema) -> AvroExport {
AvroExport {
schema,
records: Vec::new(),
}
}
#[allow(dead_code)]
pub fn add_avro_record(doc: &mut AvroExport, values: &[(&str, &str)]) {
doc.records.push(AvroRecord {
values: values
.iter()
.map(|&(k, v)| (k.to_string(), v.to_string()))
.collect(),
});
}
#[allow(dead_code)]
pub fn avro_record_count(doc: &AvroExport) -> usize {
doc.records.len()
}
#[allow(dead_code)]
pub fn avro_field_count(doc: &AvroExport) -> usize {
doc.schema.fields.len()
}
#[allow(dead_code)]
pub fn schema_to_json(schema: &AvroSchema) -> String {
let fields: Vec<String> = schema
.fields
.iter()
.map(|f| format!("{{\"name\":\"{}\",\"type\":\"{}\"}}", f.name, f.field_type))
.collect();
format!(
"{{\"type\":\"record\",\"name\":\"{}\",\"namespace\":\"{}\",\"fields\":[{}]}}",
schema.name,
schema.namespace,
fields.join(",")
)
}
#[allow(dead_code)]
pub fn record_to_json(record: &AvroRecord) -> String {
let pairs: Vec<String> = record
.values
.iter()
.map(|(k, v)| format!("\"{}\":{}", k, v))
.collect();
format!("{{{}}}", pairs.join(","))
}
#[allow(dead_code)]
pub fn records_to_json(doc: &AvroExport) -> String {
let recs: Vec<String> = doc.records.iter().map(record_to_json).collect();
format!("[{}]", recs.join(","))
}
#[allow(dead_code)]
pub fn export_mesh_avro(vertex_count: usize, index_count: usize, name: &str) -> String {
let mut schema = new_avro_schema("Mesh", "oxihuman");
add_avro_field(&mut schema, "name", "string");
add_avro_field(&mut schema, "vertex_count", "int");
add_avro_field(&mut schema, "index_count", "int");
let schema_json = schema_to_json(&schema);
let mut doc = new_avro_export(schema);
add_avro_record(
&mut doc,
&[
("name", &format!("\"{}\"", name)),
("vertex_count", &vertex_count.to_string()),
("index_count", &index_count.to_string()),
],
);
format!(
"{{\"schema\":{},\"records\":{}}}",
schema_json,
records_to_json(&doc)
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_avro_schema() {
let schema = new_avro_schema("Mesh", "ns");
assert_eq!(schema.name, "Mesh");
assert!(schema.fields.is_empty());
}
#[test]
fn test_add_avro_field() {
let mut schema = new_avro_schema("M", "ns");
add_avro_field(&mut schema, "count", "int");
assert_eq!(schema.fields.len(), 1);
}
#[test]
fn test_add_avro_record() {
let schema = new_avro_schema("M", "ns");
let mut doc = new_avro_export(schema);
add_avro_record(&mut doc, &[("count", "42")]);
assert_eq!(avro_record_count(&doc), 1);
}
#[test]
fn test_schema_to_json_contains_name() {
let schema = new_avro_schema("Vertex", "ns");
let s = schema_to_json(&schema);
assert!(s.contains("Vertex"));
}
#[test]
fn test_schema_to_json_contains_field() {
let mut schema = new_avro_schema("M", "ns");
add_avro_field(&mut schema, "x", "float");
let s = schema_to_json(&schema);
assert!(s.contains("\"name\":\"x\""));
}
#[test]
fn test_record_to_json() {
let rec = AvroRecord {
values: vec![("k".to_string(), "1".to_string())],
};
let s = record_to_json(&rec);
assert!(s.contains("\"k\":1"));
}
#[test]
fn test_records_to_json_empty() {
let schema = new_avro_schema("M", "ns");
let doc = new_avro_export(schema);
let s = records_to_json(&doc);
assert_eq!(s, "[]");
}
#[test]
fn test_avro_field_count() {
let mut schema = new_avro_schema("M", "ns");
add_avro_field(&mut schema, "a", "int");
add_avro_field(&mut schema, "b", "string");
let doc = new_avro_export(schema);
assert_eq!(avro_field_count(&doc), 2);
}
#[test]
fn test_export_mesh_avro() {
let s = export_mesh_avro(100, 300, "head");
assert!(s.contains("Mesh"));
assert!(s.contains("head"));
}
#[test]
fn test_records_to_json_single() {
let schema = new_avro_schema("M", "ns");
let mut doc = new_avro_export(schema);
add_avro_record(&mut doc, &[("n", "5")]);
let s = records_to_json(&doc);
assert!(s.starts_with('['));
}
}