html_to_email 1.0.6

A command line converts .html file to .eml file.
Documentation
use std::fs;
use std::ops::Add;
use std::path::Path;

use lettre::Message;
use lettre::message::header::{ContentTransferEncoding, ContentType};
use lettre::message::SinglePartBuilder;
use tracing::warn;
use visdom::types::{BoxDynError, Elements};
use visdom::Vis;

pub struct HtmlToEmail<'a> {
    html: &'a str,
    from: &'a str,
    to: &'a str,
}

impl<'a> HtmlToEmail<'a> {
    pub fn new(html: &'a str, from: &'a str, to: &'a str) -> Self {
        Self { html, from, to }
    }
    pub fn run(&self) -> Result<(), BoxDynError> {
        let output = self.html.trim_end_matches(".html").to_string().add(".eml");
        if Path::new(&output).exists() {
            warn!("target {} exist", output);
            return Ok(());
        }
        let data = fs::read_to_string(self.html)?;
        let doc = Vis::load(&data)?;

        self.clean_doc(&doc);
        let title = doc.find("title").text().to_string();
        let mut pb = SinglePartBuilder::new();
        {
            pb = pb.header(ContentTransferEncoding::Base64);
            pb = pb.header(ContentType::TEXT_HTML);
        }
        let part = pb.body(doc.html());

        let mut mb = Message::builder();
        {
            mb = mb.from(self.from.parse()?);
            mb = mb.to(self.to.parse()?);
            mb = mb.subject(title);
        }
        let eml = mb.singlepart(part)?;
        fs::write(output, eml.formatted())?;
        Ok(())
    }

    pub fn clean_doc(&self, doc: &Elements) {
        doc.find(r#"div:contains("ads from inoreader")"#).closest("center").remove();
        doc.find(r#"img[src='https://img.solidot.org//0/446/liiLIZF8Uh6yM.jpg']"#).remove();
        doc.find("iframe").remove();
        doc.find("link").remove();
        doc.find("script").remove();
        doc.find("button").remove();
        doc.find("input").remove();
        doc.find("*[contenteditable=true]").remove_attr("contenteditable");
    }
}