use super::join;
use crate::config::types::AssetKind;
use crate::graph::{Graph, Resolution};
use crate::markdown::frontmatter;
use serde_json::{Map, Value};
use std::collections::BTreeSet;
#[derive(Debug, Clone)]
pub struct Asset {
pub kind: AssetKind,
pub path: String,
pub stem: String,
pub fields: Option<Map<String, Value>>,
pub invalid: Option<String>,
pub body_line: usize,
pub text: String,
}
impl Asset {
pub fn field(&self, key: &str) -> Option<&str> {
self.fields.as_ref()?.get(key)?.as_str()
}
pub fn name(&self) -> &str {
self.field("name").unwrap_or(&self.stem)
}
pub fn body(&self) -> &str {
frontmatter::split(&self.text).body
}
pub fn docs(&self, g: &Graph) -> Vec<usize> {
let dir = self.path.rsplit_once('/').map(|(d, _)| d).unwrap_or("");
let mut out = BTreeSet::new();
let ok = |c: char| c.is_ascii_alphanumeric() || ":/._#-".contains(c);
for raw in self.text.split(|c: char| !ok(c)) {
let t = raw.trim_end_matches(['.', ':', '#']);
if !(t.contains(':') || t.contains('/') || t.ends_with(".md")) || t.contains("://") {
continue;
}
for cand in [t.to_string(), join(dir, t)] {
if let Resolution::Doc { idx, via_alias: false, .. } = g.resolve(&cand) {
out.insert(idx);
break;
}
}
}
out.into_iter().collect()
}
}