Skip to main content

setu_cli/parser/
parsing.rs

1use std::{fs, path::PathBuf};
2
3use pulldown_cmark::{Event, Parser, Tag, TextMergeStream};
4use reqwest::Client;
5
6use crate::{checker::MarkdownCheckResult, parser::classifier::classify_link};
7
8pub async fn parse_markdown(path: &PathBuf, concerns: &Option<Vec<u16>>) -> MarkdownCheckResult {
9    let markdown_input = match fs::read_to_string(&path) {
10        Ok(contents) => contents.to_string(),
11        Err(_) => {
12            return MarkdownCheckResult {
13                success: false,
14                checks: vec![],
15            };
16        }
17    };
18
19    let iterator = TextMergeStream::new(Parser::new(&markdown_input));
20    let mut remotes: Vec<String> = Vec::new();
21    let mut locals: Vec<String> = Vec::new();
22    let mut invalids: Vec<String> = Vec::new();
23
24    for event in iterator {
25        if let Event::Start(Tag::Link { dest_url, .. }) = event {
26            let link = dest_url.to_string();
27            match classify_link(&link) {
28                super::classifier::LinkType::Remote(url) => remotes.push(url),
29                super::classifier::LinkType::Local(url) => locals.push(url),
30                super::classifier::LinkType::Ignored => {}
31                super::classifier::LinkType::Invalid(url) => invalids.push(url),
32            }
33        }
34    }
35    let client = Client::new();
36    let remote_checks = crate::checker::remote::evaluate(path, remotes, &client, concerns).await;
37    let local_checks = crate::checker::local::evaluate(path, locals);
38    let invalid_checks = crate::checker::invalid::evaluate(path, invalids);
39
40    let checks = local_checks
41        .into_iter()
42        .chain(remote_checks)
43        .chain(invalid_checks)
44        .collect();
45
46    MarkdownCheckResult {
47        success: true,
48        checks,
49    }
50}