from_csv

Function from_csv 

Source
pub fn from_csv(csv: &str, type_name: &str, schema: &[&str]) -> Result<Document>
Expand description

Parse CSV string into a HEDL document with default configuration.

This is the primary entry point for CSV parsing. It uses sensible defaults:

  • Comma delimiter
  • Headers expected in first row
  • Whitespace trimming enabled
  • 1 million row limit for security

§Arguments

  • csv - The CSV string to parse
  • type_name - The HEDL type name for rows (e.g., “Person”)
  • schema - Column names excluding the ‘id’ column (which is always first)

§Returns

A Document containing a single matrix list with the parsed data, or an error if parsing fails.

§Errors

Returns HedlError in the following cases:

  • Syntax: Malformed CSV records or invalid UTF-8
  • Schema: Missing ID column or field count mismatch
  • Semantic: Empty ID field
  • Security: Row count exceeds maximum (default 1M rows)

§Type Inference

Values are automatically inferred from CSV text:

  • Empty string or ~Value::Null
  • true/falseValue::Bool
  • Integer pattern → Value::Int (e.g., “42”, “-123”)
  • Float pattern → Value::Float (e.g., “3.14”, “1.5e10”)
  • Special floats: NaN, Infinity, -Infinity
  • @id or @Type:idValue::Reference
  • $(expr)Value::Expression
  • [1,2,3]Value::Tensor
  • Otherwise → Value::String

§Examples

§Basic Usage

use hedl_csv::from_csv;
use hedl_core::Value;

let csv_data = "id,name,age\n1,Alice,30\n2,Bob,25";
let doc = from_csv(csv_data, "Person", &["name", "age"]).unwrap();

// Access the parsed data
let list = doc.get("persons").unwrap().as_list().unwrap();
assert_eq!(list.rows.len(), 2);
assert_eq!(list.rows[0].id, "1");

§Mixed Type Inference

use hedl_csv::from_csv;
use hedl_core::Value;

let csv_data = "id,value\n1,42\n2,3.14\n3,true\n4,hello";
let doc = from_csv(csv_data, "Item", &["value"]).unwrap();

let list = doc.get("items").unwrap().as_list().unwrap();
assert!(matches!(list.rows[0].fields[1], Value::Int(42)));
assert!(matches!(list.rows[1].fields[1], Value::Float(f) if (f - 3.14).abs() < 0.001));
assert!(matches!(list.rows[2].fields[1], Value::Bool(true)));
assert!(matches!(list.rows[3].fields[1], Value::String(_)));

§References

use hedl_csv::from_csv;

let csv_data = "id,owner\n1,@user1\n2,@User:alice";
let doc = from_csv(csv_data, "Item", &["owner"]).unwrap();

let list = doc.get("items").unwrap().as_list().unwrap();
let ref1 = list.rows[0].fields[1].as_reference().unwrap();
assert_eq!(&*ref1.id, "user1");
assert_eq!(ref1.type_name, None); // Local reference

let ref2 = list.rows[1].fields[1].as_reference().unwrap();
assert_eq!(&*ref2.id, "alice");
assert_eq!(ref2.type_name.as_deref(), Some("User")); // Qualified reference

§Performance

  • Streaming: Processes CSV row-by-row to minimize memory usage
  • Memory bound: O(rows × columns) space complexity
  • Time complexity: O(rows × columns) with efficient parsing

For very large files, consider using from_csv_reader for file I/O or increasing max_rows via from_csv_with_config.

§See Also

  • from_csv_with_config - For custom delimiters, row limits, etc.
  • from_csv_reader - For parsing from files or network streams