use cabin_core::CompilerKind;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Dialect {
GnuLike,
Msvc,
}
impl Dialect {
#[must_use]
pub fn from_compiler_kind(kind: CompilerKind) -> Self {
if kind.speaks_msvc_dialect() {
Dialect::Msvc
} else {
Dialect::GnuLike
}
}
#[must_use]
pub fn host_default() -> Self {
if cfg!(windows) {
Dialect::Msvc
} else {
Dialect::GnuLike
}
}
#[must_use]
pub fn object_extension(self) -> &'static str {
match self {
Dialect::GnuLike => "o",
Dialect::Msvc => "obj",
}
}
#[must_use]
pub fn static_library_name(self, stem: &str) -> String {
match self {
Dialect::GnuLike => format!("lib{stem}.a"),
Dialect::Msvc => format!("{stem}.lib"),
}
}
#[must_use]
pub fn executable_name(self, stem: &str) -> String {
match self {
Dialect::GnuLike => stem.to_owned(),
Dialect::Msvc => format!("{stem}.exe"),
}
}
#[must_use]
pub fn ninja_deps(self) -> NinjaDeps {
match self {
Dialect::GnuLike => NinjaDeps::Gcc,
Dialect::Msvc => NinjaDeps::Msvc {
prefix: "Note: including file:",
},
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NinjaDeps {
Gcc,
Msvc {
prefix: &'static str,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn msvc_compiler_selects_msvc_dialect() {
assert_eq!(
Dialect::from_compiler_kind(CompilerKind::Msvc),
Dialect::Msvc
);
}
#[test]
fn clang_cl_selects_msvc_dialect() {
assert_eq!(
Dialect::from_compiler_kind(CompilerKind::ClangCl),
Dialect::Msvc
);
}
#[test]
fn gcc_clang_unknown_select_gnu_dialect() {
for kind in [
CompilerKind::Clang,
CompilerKind::AppleClang,
CompilerKind::Gcc,
CompilerKind::Unknown,
] {
assert_eq!(Dialect::from_compiler_kind(kind), Dialect::GnuLike);
}
}
#[test]
fn artifact_names_follow_the_dialect() {
assert_eq!(Dialect::GnuLike.object_extension(), "o");
assert_eq!(Dialect::Msvc.object_extension(), "obj");
assert_eq!(Dialect::GnuLike.static_library_name("greet"), "libgreet.a");
assert_eq!(Dialect::Msvc.static_library_name("greet"), "greet.lib");
assert_eq!(Dialect::GnuLike.executable_name("app"), "app");
assert_eq!(Dialect::Msvc.executable_name("app"), "app.exe");
}
#[test]
fn ninja_deps_mode_follows_the_dialect() {
assert_eq!(Dialect::GnuLike.ninja_deps(), NinjaDeps::Gcc);
assert_eq!(
Dialect::Msvc.ninja_deps(),
NinjaDeps::Msvc {
prefix: "Note: including file:"
}
);
}
}