use indexmap::IndexMap;
use super::Quill;
use crate::quill::CardSchema;
use crate::{Card, Document, Payload, QuillReference, QuillValue, SeedOverlay};
fn seed_parts(schema: &CardSchema, overlay: Option<&SeedOverlay>) -> (Payload, String) {
let mut merged: IndexMap<String, QuillValue> = IndexMap::new();
for (name, field) in &schema.fields {
if let Some(example) = &field.example {
merged.insert(name.clone(), example.clone());
}
}
if let Some(overlay) = overlay {
for (name, value) in &overlay.fields {
if schema.fields.contains_key(name) {
merged.insert(name.clone(), value.clone());
}
}
}
let mut entries: Vec<(String, QuillValue)> = merged.into_iter().collect();
entries.sort_by_key(|(name, _)| {
schema
.fields
.get(name)
.map(|f| f.ui_order())
.unwrap_or(i32::MAX)
});
let fields: IndexMap<String, QuillValue> = entries.into_iter().collect();
let body = if schema.body_enabled() {
overlay
.and_then(|o| o.body.clone())
.or_else(|| schema.body.as_ref().and_then(|b| b.example.clone()))
.unwrap_or_default()
} else {
String::new()
};
(Payload::from_index_map(fields), body)
}
fn main_reference(quill: &Quill) -> QuillReference {
let config = quill.config();
format!("{}@{}", config.name, config.version)
.parse()
.unwrap_or_else(|_| QuillReference::latest(config.name.clone()))
}
pub(crate) fn seed_main(quill: &Quill) -> Card {
let (mut payload, body) = seed_parts(&quill.config().main, None);
payload.set_quill(main_reference(quill));
payload.set_kind("main");
Card::from_parts(payload, body)
}
pub(crate) fn seed_card_for_kind(
quill: &Quill,
card_kind: &str,
overlay: Option<&SeedOverlay>,
) -> Option<Card> {
let schema = quill.config().card_kind(card_kind)?;
Some(seed_composable(schema, overlay))
}
fn seed_composable(schema: &CardSchema, overlay: Option<&SeedOverlay>) -> Card {
let (mut payload, body) = seed_parts(schema, overlay);
payload.set_kind(schema.name.clone());
Card::from_parts(payload, body)
}
pub(crate) fn seed_document(quill: &Quill) -> Document {
let main = seed_main(quill);
let cards = quill
.config()
.card_kinds
.iter()
.map(|schema| seed_composable(schema, None))
.collect();
Document::from_main_and_cards(main, cards, Vec::new())
}
#[cfg(test)]
mod tests;