1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;

use crate::markup::MarkupFile;
pub mod cli;
pub mod file_traversal;
pub mod link_extractors;
pub mod link_validator;
pub mod logger;
pub mod markup;
pub use colored::*;

use link_validator::LinkCheckResult;

#[derive(Default)]
pub struct Config {
    pub log_level: logger::LogLevel,
    pub folder: String,
    pub markup_types: Vec<markup::MarkupType>,
}

pub fn run(config: &Config) -> Result<(), ()> {
    let mut files: Vec<MarkupFile> = Vec::new();
    file_traversal::find(&config, &mut files);

    let mut warnings = 0;
    let mut link_ctr = 0;
    let mut invalid_links = vec![];
    for file in files {
        let links = link_extractors::link_extractor::find_links(&file);
        for link in links {
            link_ctr += 1;
            let result = link_validator::check(&file.path, &link.target);
            match result {
                LinkCheckResult::Ok => {
                    println!(
                        "[{:^4}] {} ({}, {}) => {}",
                        "OK".green(),
                        file.path,
                        link.line,
                        link.column,
                        link.target
                    );
                }
                LinkCheckResult::NotImplemented(msg) => {
                    println!(
                        "[{:^4}] {} ({}, {}) => {}. {}",
                        "Warn".yellow(),
                        file.path,
                        link.line,
                        link.column,
                        link.target,
                        msg
                    );
                    warnings += 1;
                }
                LinkCheckResult::Warning(msg) => {
                    println!(
                        "[{:^4}] {} ({}, {}) => {}. {}",
                        "Warn".yellow(),
                        file.path,
                        link.line,
                        link.column,
                        link.target,
                        msg
                    );
                    warnings += 1;
                }
                LinkCheckResult::Failed(msg) => {
                    let error_msg = format!(
                        "[{:^4}] {} ({}, {}) => {}. {}",
                        "Err".red(),
                        file.path,
                        link.line,
                        link.column,
                        link.target,
                        msg
                    );
                    eprintln!("{}", &error_msg);
                    invalid_links.push(error_msg);
                }
            }
        }
    }

    println!();
    println!("Result:");
    println!();
    println!("Links    {}", link_ctr);
    println!("Warnings {}", warnings);
    println!("Errors   {}", &invalid_links.len());
    println!();

    if !invalid_links.is_empty() {
        eprintln!();
        eprintln!("The following links could not be resolved:");
        println!();
        for il in invalid_links {
            eprintln!("{}", il);
        }
        println!();
        Err(())
    } else {
        Ok(())
    }
}