Split csv module
This commit is contained in:
parent
d90fb5c7fe
commit
25e80f74a8
5 changed files with 80 additions and 54 deletions
|
@ -1,53 +1,29 @@
|
||||||
|
mod reader;
|
||||||
|
mod record;
|
||||||
|
mod table;
|
||||||
|
mod writer;
|
||||||
|
|
||||||
|
pub use reader::CsvReader;
|
||||||
|
pub use record::CsvRecord;
|
||||||
|
pub use table::CsvTable;
|
||||||
|
pub use writer::CsvWriter;
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime};
|
use chrono::{DateTime, NaiveDateTime};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
pub struct CsvRecord{
|
|
||||||
pub timestamp: NaiveDateTime,
|
|
||||||
#[serde(with = "string_to_escape")]
|
|
||||||
pub comment: String,
|
|
||||||
pub tag: String,
|
|
||||||
pub count: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod string_to_escape {
|
|
||||||
use serde::{Deserialize, Deserializer, Serializer};
|
|
||||||
|
|
||||||
pub fn deserialize<'de, D>(d: D) -> Result<String, D::Error>
|
|
||||||
where D: Deserializer<'de>
|
|
||||||
{
|
|
||||||
Ok(String::deserialize(d)?
|
|
||||||
.replace("\\n", "\n")
|
|
||||||
.replace("\\t", "\t")
|
|
||||||
.replace("\\\"", "\"")
|
|
||||||
.replace("\\\\", "\\")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
pub fn serialize<S>(s: &str, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where S: Serializer
|
|
||||||
{
|
|
||||||
serializer.serialize_str(&s
|
|
||||||
|
|
||||||
.replace("\n", "\\n")
|
|
||||||
.replace("\t", "\\t")
|
|
||||||
.replace("\"", "\\\"")
|
|
||||||
.replace("\\", "\\\\")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use chrono::{NaiveDate, NaiveTime};
|
use chrono::{NaiveDate, NaiveTime};
|
||||||
|
|
||||||
const RECORD_CSV:&str = r#"timestamp,comment,tag,count
|
const RECORD_CSV:&str = r#"timestamp,comment,tag,count
|
||||||
2025-05-01T12:34:56,test\ntest,test,1"#;
|
2025-05-01T12:34:56,"test
|
||||||
|
test",test,1
|
||||||
|
"#;
|
||||||
|
|
||||||
fn get_record_struct() -> Vec<CsvRecord>{
|
fn get_records() -> Vec<CsvRecord>{
|
||||||
vec![CsvRecord {
|
vec![CsvRecord {
|
||||||
timestamp: NaiveDate::from_ymd_opt(2025, 5, 1)
|
timestamp: NaiveDate::from_ymd_opt(2025, 5, 1)
|
||||||
.unwrap().and_hms_micro_opt(12, 34, 56, 0).unwrap(),
|
.unwrap().and_hms_micro_opt(12, 34, 56, 0).unwrap(),
|
||||||
|
@ -58,16 +34,6 @@ test".to_owned(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn serialize_string() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn deserialize_string() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_record() {
|
fn deserialize_record() {
|
||||||
println!("{:?}", RECORD_CSV);
|
println!("{:?}", RECORD_CSV);
|
||||||
|
@ -84,14 +50,18 @@ test".to_owned(),
|
||||||
let record: CsvRecord = raw_record.deserialize(Some(&headers)).unwrap();
|
let record: CsvRecord = raw_record.deserialize(Some(&headers)).unwrap();
|
||||||
records.push(record);
|
records.push(record);
|
||||||
}
|
}
|
||||||
assert_eq!(records, get_record_struct());
|
assert_eq!(records, get_records());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_record() {
|
fn serialize_record() {
|
||||||
todo!()
|
let buf : Vec<u8> = Vec::new();
|
||||||
|
let mut wtr = csv::Writer::from_writer(buf);
|
||||||
|
for record in get_records().into_iter() {
|
||||||
|
wtr.serialize(record).unwrap();
|
||||||
|
}
|
||||||
|
wtr.flush().unwrap();
|
||||||
|
assert_eq!(RECORD_CSV, &String::from_utf8(wtr.into_inner().unwrap()).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
9
dpts-core/src/csv/reader.rs
Normal file
9
dpts-core/src/csv/reader.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pub struct CsvReader<T> {
|
||||||
|
inner: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> CsvReader<T> {
|
||||||
|
pub fn into_inner(self) -> T {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
19
dpts-core/src/csv/record.rs
Normal file
19
dpts-core/src/csv/record.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
use chrono::{DateTime, NaiveDateTime};
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||||
|
pub struct CsvRecord{
|
||||||
|
pub timestamp: NaiveDateTime,
|
||||||
|
pub comment: String,
|
||||||
|
pub tag: String,
|
||||||
|
pub count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<crate::entity::RecordDetailModel> for CsvRecord{
|
||||||
|
type Error = crate::error::Error;
|
||||||
|
fn try_from(model: crate::entity::RecordDetailModel) -> Result<Self, Self::Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
19
dpts-core/src/csv/table.rs
Normal file
19
dpts-core/src/csv/table.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
use crate::error::Error;
|
||||||
|
use super::CsvRecord;
|
||||||
|
pub struct CsvTable{
|
||||||
|
inner: Vec<CsvRecord>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CsvTable {
|
||||||
|
pub fn into_inner(self) -> Vec<CsvRecord> {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<CsvRecord>> for CsvTable {
|
||||||
|
fn from(v: Vec<CsvRecord>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
dpts-core/src/csv/writer.rs
Normal file
9
dpts-core/src/csv/writer.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pub struct CsvWriter<T> {
|
||||||
|
inner: T
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> CsvWriter<T> {
|
||||||
|
pub fn into_inner(self) -> T {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue