add vars
This commit is contained in:
parent
d8ce9df7bc
commit
168dddd6b1
4 changed files with 97 additions and 15 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -344,6 +344,7 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
name = "mdq"
|
name = "mdq"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"comfy-table",
|
"comfy-table",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
@ -596,6 +597,8 @@ name = "txd"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -14,3 +14,4 @@ serde_json = "1.0.107"
|
||||||
comfy-table = "7.1.0"
|
comfy-table = "7.1.0"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
|
chrono = "0.4.31"
|
||||||
|
|
107
src/lib.rs
107
src/lib.rs
|
@ -1,3 +1,5 @@
|
||||||
|
use txd::DataType;
|
||||||
|
|
||||||
/// get frontmatter from markdown document
|
/// get frontmatter from markdown document
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_frontmatter(markdown: &str) -> Option<String> {
|
pub fn get_frontmatter(markdown: &str) -> Option<String> {
|
||||||
|
@ -12,6 +14,23 @@ pub fn get_frontmatter(markdown: &str) -> Option<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn system_time_to_date_time(t: std::time::SystemTime) -> chrono::DateTime<chrono::Utc> {
|
||||||
|
let (sec, nsec) = match t.duration_since(std::time::UNIX_EPOCH) {
|
||||||
|
Ok(dur) => (dur.as_secs() as i64, dur.subsec_nanos()),
|
||||||
|
Err(e) => {
|
||||||
|
// unlikely but should be handled
|
||||||
|
let dur = e.duration();
|
||||||
|
let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos());
|
||||||
|
if nsec == 0 {
|
||||||
|
(-sec, 0)
|
||||||
|
} else {
|
||||||
|
(-sec - 1, 1_000_000_000 - nsec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
chrono::TimeZone::timestamp_opt(&chrono::Utc, sec, nsec).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Document {
|
pub struct Document {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
@ -60,26 +79,84 @@ pub fn scan_dir(dir: &str) -> Index {
|
||||||
/// Get a key from document.
|
/// Get a key from document.
|
||||||
/// This will return internal properties first, then it will search the document frontmatter for the key and return it. If nothing was found an empty string is returned.
|
/// This will return internal properties first, then it will search the document frontmatter for the key and return it. If nothing was found an empty string is returned.
|
||||||
fn get_key(d: &Document, key: &str) -> String {
|
fn get_key(d: &Document, key: &str) -> String {
|
||||||
if key == "file.title" {
|
match key {
|
||||||
let path = std::path::Path::new(&d.path);
|
"file.title" => {
|
||||||
return path.file_stem().unwrap().to_str().unwrap().to_string();
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path.file_stem().unwrap().to_str().unwrap().to_string();
|
||||||
|
}
|
||||||
|
"file.name" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path.file_name().unwrap().to_str().unwrap().to_string();
|
||||||
|
}
|
||||||
|
"file.parent" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.file_name()
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
}
|
||||||
|
"file.folder" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path.parent().unwrap().to_str().unwrap().to_string();
|
||||||
|
}
|
||||||
|
"file.ext" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path.extension().unwrap().to_str().unwrap().to_string();
|
||||||
|
}
|
||||||
|
"file.size" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return path.metadata().unwrap().len().to_string();
|
||||||
|
}
|
||||||
|
"file.ctime" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return system_time_to_date_time(path.metadata().unwrap().created().unwrap())
|
||||||
|
.to_rfc3339();
|
||||||
|
}
|
||||||
|
"file.cday" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return system_time_to_date_time(path.metadata().unwrap().created().unwrap())
|
||||||
|
.format("%Y-%m-%d")
|
||||||
|
.to_string();
|
||||||
|
}
|
||||||
|
"file.mtime" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return system_time_to_date_time(path.metadata().unwrap().modified().unwrap())
|
||||||
|
.to_rfc3339();
|
||||||
|
}
|
||||||
|
"file.mday" => {
|
||||||
|
let path = std::path::Path::new(&d.path);
|
||||||
|
return system_time_to_date_time(path.metadata().unwrap().modified().unwrap())
|
||||||
|
.format("%Y-%m-%d")
|
||||||
|
.to_string();
|
||||||
|
}
|
||||||
|
"file.path" => {
|
||||||
|
return d.path.clone();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
if let Some(val) = d.frontmatter.as_mapping().unwrap().get(key) {
|
if let Some(val) = d.frontmatter.as_mapping().unwrap().get(key) {
|
||||||
// TODO : Fix format
|
stringify(val)
|
||||||
match val {
|
|
||||||
serde_yaml::Value::Null => String::new(),
|
|
||||||
serde_yaml::Value::Bool(b) => b.to_string(),
|
|
||||||
serde_yaml::Value::Number(n) => n.to_string(),
|
|
||||||
serde_yaml::Value::String(s) => s.to_owned(),
|
|
||||||
serde_yaml::Value::Sequence(_v) => todo!(),
|
|
||||||
serde_yaml::Value::Mapping(_o) => todo!(),
|
|
||||||
serde_yaml::Value::Tagged(_) => unimplemented!(),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stringify(val: &serde_yaml::Value) -> String {
|
||||||
|
match val {
|
||||||
|
serde_yaml::Value::Null => String::new(),
|
||||||
|
serde_yaml::Value::Bool(b) => b.to_string(),
|
||||||
|
serde_yaml::Value::Number(n) => n.to_string(),
|
||||||
|
serde_yaml::Value::String(s) => s.to_owned(),
|
||||||
|
serde_yaml::Value::Sequence(_) => serde_json::to_string(&val).unwrap(),
|
||||||
|
serde_yaml::Value::Mapping(_o) => todo!(),
|
||||||
|
serde_yaml::Value::Tagged(_) => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Table = Vec<Vec<String>>;
|
type Table = Vec<Vec<String>>;
|
||||||
|
|
||||||
/// Build a table with specified columns from index
|
/// Build a table with specified columns from index
|
||||||
|
@ -121,13 +198,13 @@ pub fn filter_documents(i: Index, filters: &[txd::filter::Filter]) -> Index {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !a.same_as(&b) {
|
if !a.same_as(&b) && !matches!(a, DataType::List(_)) {
|
||||||
log::debug!("trying to cast a to string because of different types");
|
log::debug!("trying to cast a to string because of different types");
|
||||||
a = txd::DataType::String(a_str);
|
a = txd::DataType::String(a_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !a.compare(f.1, b) {
|
if !a.compare(f.1, b) {
|
||||||
is_included = false
|
is_included = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_included {
|
if is_included {
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod args;
|
||||||
// TODO : Add debug logging
|
// TODO : Add debug logging
|
||||||
// TODO : Add documentation comments
|
// TODO : Add documentation comments
|
||||||
// TODO : Add tests
|
// TODO : Add tests
|
||||||
|
// TODO : Add GROUP BY Function
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
Loading…
Add table
Reference in a new issue