couchdb-orm 0.1.6

couchdb-orm Copyright (C) 2020-2023 OpenToolAdd This program comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under certain conditions; type `show-license' for details. A CLI ORM to manage some Databases operations like migration, schema creation, etc.... For the moment it only handle CouchDB.
Documentation
// Copyright (C) 2020-2023  OpenToolAdd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// contact: contact@tool-add.com

use std::fs;
use std::path::{PathBuf};
use std::str::FromStr;

pub fn root_path(rootdir: &PathBuf) -> PathBuf {
  rootdir.join("_meta/src/migrations/")
}

pub fn db_list(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  Ok(
    fs::read_dir(root_path(rootdir))?
      .map(|res| res.expect("path should be a path").path())
      .filter(|e| e.is_dir())
      .map(|e| format!("{}", e.file_name().unwrap().to_str().unwrap().to_string()))
      .collect()
  )
}

pub fn dbs(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  Ok(
    db_list(rootdir)?
    .iter()
    .map(|db| {
        format!(
            include_str!("../../../static/templates/db_migrations.tpl"),
            db,
            {
                // capitalize first letter
                let mut c = db.chars();
                match c.next() {
                    None => String::new(),
                    Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
                }
            }
        )
    })
    .collect()
  )
}

pub fn available_migrations(rootdir: &PathBuf) -> Result<Vec<Vec<PathBuf>>, Box<dyn std::error::Error>> {
  db_list(rootdir)?
    .iter()
    .map(|db| {
        let migrations_path: PathBuf = PathBuf::from_str(&format!(
            "{}/_meta/src/migrations/{}",
            rootdir.to_str().unwrap(),
            db
        )).unwrap();
        Ok(
          fs::read_dir(&migrations_path)
            .map(|res| res.map(|e| e.as_ref().expect("could not read reference").path()))
            .expect("Error in read_dir:  migrations_path")
        )
    })
    .map(|a| {
      a.map(|r|
        r.filter(|e| e.file_name().unwrap() != "mod.rs")
        .collect()
      )
    }).collect()
}

pub fn available_migrations_enum(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  Ok(
    available_migrations(rootdir)?
        .iter()
        .map(|a| {
            a.iter()
                .map(|e| {
                    let mut s = e
                        .file_name()
                        .unwrap()
                        .to_str()
                        .unwrap()
                        .to_string()
                        .replace(".rs", ",");
                    s.push_str("\n");
                    s
                })
                .collect()
        })
        .collect()
  )
}

pub fn db_actions(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  let available_migrations_enum: Vec<String> = available_migrations_enum(&rootdir)?;
  Ok(
    db_list(&rootdir)?
        .iter()
        .enumerate()
        .map(|(index, db)| {
            format!(
                include_str!("../../../static/templates/migrations_actions.tpl"),
                db, available_migrations_enum[index]
            )
        })
        .collect()
  )
}

pub fn db_match(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  Ok(
    available_migrations(rootdir)?
        .iter()
        .map(|a| {
            a.iter()
                .enumerate()
                .map(|(index, file)| {
                    format!(
                        include_str!("../../../static/templates/migrations_match.tpl"),
                        index,
                        file.file_name()
                            .unwrap()
                            .to_str()
                            .unwrap()
                            .to_string()
                            .replace(".rs", "")
                    )
                })
                .collect()
        })
        .collect()
  )
}

pub fn db_matches(rootdir: &PathBuf) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  let db_match = db_match(&rootdir)?;
  Ok(
    db_list(&rootdir)?
        .iter()
        .enumerate()
        .map(|(index, db)| {
            format!(
                include_str!("../../../static/templates/migrations_db_matches.tpl"),
                index,
                {
                    // capitalize first letter
                    let mut c = db.chars();
                    match c.next() {
                        None => String::new(),
                        Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
                    }
                },
                db_match[index]
            )
        })
        .collect()
  )
}