microformats 0.18.0

A union library of the Microformats types and associated parser.
Documentation
// This aims to cache the issue at
// https://gitlab.com/maxburon/microformats-parser/-/issues/7#note_951502062
#[cfg(test)]
#[tracing_test::traced_test]
#[test]
fn issue_7() -> Result<(), crate::Error> {
    use crate::parse::Parser;

    let html = r#"
<article class="h-entry">
  <header class="metadata">
    <div>
      <span>
        <a class="u-url u-uid" href="https://fireburn.ru/posts/est-eligendi-deleniti">
          <time class="dt-published" datetime="2022-05-16T20:41:45.032834285+03:00">Mon May 16 20:41:45 2022</time>
        </a>
      </span>
    </div>
  </header>
  <main class="e-content">
    <p>Aut repellat tempora. Incidunt dolorum earum iste. Quis velit necessitatibus numquam et quaerat recusandae. Eius harum maxime qui.</p>
  </main>
  <footer class="webinteractions">
    <ul class="counters">
      <li><span class="icon">❤️</span><span class="counter">0</span></li>
      <li><span class="icon">💬</span><span class="counter">0</span></li>
      <li><span class="icon">🔄</span><span class="counter">0</span></li>
      <li><span class="icon">🔖</span><span class="counter">0</span></li>
    </ul>
  </footer>
</article>
    "#;

    let json_str = r#"
{
    "items": [
        {
            "type": ["h-entry"], 
            "properties": {
                "uid": ["https://fireburn.ru/posts/est-eligendi-deleniti"],
                "url": ["https://fireburn.ru/posts/est-eligendi-deleniti"], 
                "published": ["2022-05-16T20:41:45.032834285+03:00"], 
                "content": [{
                    "html": "<p>Aut repellat tempora. Incidunt dolorum earum iste. Quis velit necessitatibus numquam et quaerat recusandae. Eius harum maxime qui.</p>",
                    "value": "Aut repellat tempora. Incidunt dolorum earum iste. Quis velit necessitatibus numquam et quaerat recusandae. Eius harum maxime qui."
                }]
            }
        }
    ]
}
    "#;

    let expected_json_mf2_item = serde_json::from_str(json_str.trim())
        .map_err(microformats_types::Error::from)
        .map_err(crate::Error::from)
        .map(|document: microformats_types::Document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    let parsed_html_mf2_json = Parser::from_html(html.to_string())
        .and_then(|mut parser| parser.into_document("https://fireburn.ru".parse().ok()))
        .map(|document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    similar_asserts::assert_serde_eq!(expected_json_mf2_item, parsed_html_mf2_json);

    Ok(())
}

// This aims to capture the issue at
// https://gitlab.com/maxburon/microformats-parser/-/issues/22
#[cfg(test)]
#[tracing_test::traced_test]
#[test]
fn issue_22() -> Result<(), crate::Error> {
    use crate::parse::Parser;
    let html = include_str!("issue-22.html");
    let json_str = include_str!("issue-22.json");

    tracing::trace!("parsing the MF2+JSON");
    let expected_json_mf2_item = serde_json::from_str(json_str)
        .map_err(microformats_types::Error::from)
        .map_err(crate::Error::from)
        .map(|document: microformats_types::Document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    tracing::trace!("parsing the MF2+HTML");
    let parsed_html_mf2_json = Parser::from_html(html.to_string())
        .and_then(|mut parser| parser.into_document("https://slatecave.net".parse().ok()))
        .map(|document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    similar_asserts::assert_serde_eq!(expected: expected_json_mf2_item, actual: parsed_html_mf2_json);

    Ok(())
}

// This aims to capture the issue at
// https://gitlab.com/maxburon/microformats-parser/-/issues/24
#[cfg(test)]
#[tracing_test::traced_test]
#[test]
fn issue_24() -> Result<(), crate::Error> {
    use crate::parse::Parser;
    let html = include_str!("issue-24.html");
    let json_str = include_str!("issue-24.json");

    tracing::trace!("parsing the MF2+JSON");
    let expected_json_mf2_item = serde_json::from_str(json_str)
        .map_err(microformats_types::Error::from)
        .map_err(crate::Error::from)
        .map(|document: microformats_types::Document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    tracing::trace!("parsing the MF2+HTML");
    let parsed_html_mf2_json = Parser::from_html(html.to_string())
        .and_then(|mut parser| parser.into_document("https://indiepass.app".parse().ok()))
        .map(|document| document.items[0].clone())
        .and_then(|d| {
            serde_json::to_value(d)
                .map_err(microformats_types::Error::from)
                .map_err(crate::Error::from)
        })?;

    similar_asserts::assert_serde_eq!(expected: expected_json_mf2_item, actual: parsed_html_mf2_json);

    Ok(())
}