ldp 0.1.0

A library to assist with the creation and maintenance of remote RDF data via LDP
use crate::vocab;
use http::{HeaderMap, HeaderValue};
use oxigraph::model::{NamedNode, NamedNodeRef};

/// [Request preferences](https://www.w3.org/TR/ldp/#prefer-parameters)
#[derive(Clone, Debug)]
pub enum Preference {
    Containment,
    Membership,
    MinimalContainer,
    Other(NamedNode),
}

impl Preference {
    pub fn as_named_node_ref(&self) -> NamedNodeRef<'_> {
        match self {
            Preference::Containment => vocab::ldp::PREFER_CONTAINMENT,
            Preference::Membership => vocab::ldp::PREFER_MEMBERSHIP,
            Preference::MinimalContainer => vocab::ldp::PREFER_MINIMAL_CONTAINER,
            Preference::Other(preference) => preference.as_ref(),
        }
    }
}

pub fn header_for_preferences<'a, I, J>(include: I, omit: J) -> crate::Result<HeaderMap>
where
    I: IntoIterator<Item = &'a Preference>,
    J: IntoIterator<Item = &'a Preference>,
{
    let include_str = include
        .into_iter()
        .map(|preference| preference.as_named_node_ref().as_str().to_string())
        .collect::<Vec<_>>()
        .join(" ");

    let omit_str = omit
        .into_iter()
        .map(|preference| preference.as_named_node_ref().as_str().to_string())
        .collect::<Vec<_>>()
        .join(" ");

    let mut value = String::from("return=representation");

    if !include_str.is_empty() {
        value = format!("{value}; include=\"{include_str}\"");
    }

    if !omit_str.is_empty() {
        value = format!("{value}; omit=\"{omit_str}\"");
    }

    let header_value =
        HeaderValue::from_str(&value).expect("Failed to produce Prefer header value");

    Ok(HeaderMap::from_iter([(
        crate::header::PREFER,
        header_value,
    )]))
}