Move 'PackageName' and associated methods in its own module.

This is a bit cleaner, as the 'cmd/new' had many on-the-fly functions
  which are better scoped inside this module.

  Plus, it plays nicely with the std::str::FromStr trait definition.
This commit is contained in:
KtorZ
2023-01-14 22:01:55 +01:00
parent bfeb26c9a9
commit 0771ab24bd
12 changed files with 174 additions and 169 deletions

View File

@@ -1,43 +0,0 @@
use std::fmt;
use owo_colors::OwoColorize;
use thiserror::Error;
#[derive(Debug, Error, miette::Diagnostic)]
pub enum Error {
#[error("{} is not a valid project name: {}", name.red(), reason.to_string())]
InvalidProjectName {
name: String,
reason: InvalidProjectNameReason,
},
#[error("A project named {} already exists.", name.red())]
ProjectExists { name: String },
}
#[derive(Debug, Clone, Copy)]
pub enum InvalidProjectNameReason {
AikenPrefix,
AikenReservedModule,
Format,
}
impl fmt::Display for InvalidProjectNameReason {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
InvalidProjectNameReason::AikenPrefix => write!(f, "it's a reserved word in Aiken."),
InvalidProjectNameReason::AikenReservedModule => {
write!(f, "it's a reserved module name in Aiken.")
}
InvalidProjectNameReason::Format => write!(
f,
"it is malformed.\n\nProjects must be named as:\n\n\t\
{}/{}\n\nEach part must start with a lowercase letter \
and may only contain lowercase letters, numbers, hyphens or underscores.\
\nFor example,\n\n\t{}",
"{owner}".bright_blue(),
"{project}".bright_blue(),
"aiken-lang/stdlib".bright_blue(),
),
}
}
}

View File

@@ -2,7 +2,6 @@ pub mod build;
pub mod check;
pub mod deps;
pub mod docs;
pub mod error;
pub mod fmt;
pub mod lsp;
pub mod new;

View File

@@ -1,11 +1,15 @@
use aiken_project::config::PackageName;
use aiken_project::{
config::Config,
package_name::{self, PackageName},
};
use indoc::{formatdoc, indoc};
use miette::IntoDiagnostic;
use owo_colors::OwoColorize;
use std::path::PathBuf;
use std::{fs, path::Path};
use super::error::{Error, InvalidProjectNameReason};
use std::{
fs,
path::{Path, PathBuf},
str::FromStr,
};
#[derive(clap::Args)]
/// Create a new Aiken project
@@ -18,14 +22,9 @@ pub struct Args {
}
pub fn exec(args: Args) -> miette::Result<()> {
validate_name(&args.name)?;
let package_name = package_name_from_str(&args.name)?;
let package_name = PackageName::from_str(&args.name).into_diagnostic()?;
create_project(args, &package_name)?;
print_success_message(&package_name);
Ok(())
}
@@ -33,7 +32,7 @@ fn create_project(args: Args, package_name: &PackageName) -> miette::Result<()>
let root = PathBuf::from(&package_name.repo);
if root.exists() {
Err(Error::ProjectExists {
Err(package_name::Error::ProjectExists {
name: package_name.repo.clone(),
})?;
}
@@ -198,49 +197,3 @@ fn gitignore(root: &Path) -> miette::Result<()> {
Ok(())
}
fn validate_name(name: &str) -> Result<(), Error> {
if name.starts_with("aiken_") {
Err(Error::InvalidProjectName {
name: name.to_string(),
reason: InvalidProjectNameReason::AikenPrefix,
})
} else if name == "aiken" {
Err(Error::InvalidProjectName {
name: name.to_string(),
reason: InvalidProjectNameReason::AikenReservedModule,
})
} else if !regex::Regex::new("^[a-z0-9_-]+/[a-z0-9_-]+$")
.expect("regex could not be compiled")
.is_match(name)
{
Err(Error::InvalidProjectName {
name: name.to_string(),
reason: InvalidProjectNameReason::Format,
})
} else {
Ok(())
}
}
fn package_name_from_str(name: &str) -> Result<PackageName, Error> {
let mut name_split = name.split('/');
let owner = name_split
.next()
.ok_or_else(|| Error::InvalidProjectName {
name: name.to_string(),
reason: InvalidProjectNameReason::Format,
})?
.to_string();
let repo = name_split
.next()
.ok_or_else(|| Error::InvalidProjectName {
name: name.to_string(),
reason: InvalidProjectNameReason::Format,
})?
.to_string();
Ok(PackageName { owner, repo })
}