use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use crate::rustc_error_messages::LongTyPath;
use alloc::borrow::Cow;
use core::fmt;
use core::num::ParseIntError;
use eko::path::{Path, PathBuf};
use crate::rustc_span::edition::Edition;
use crate::rustc_error_messages::{DiagArgValue, IntoDiagArg};
pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
impl IntoDiagArg for DiagArgFromDisplay<'_> {
fn into_diag_arg(self, path: &mut LongTyPath) -> DiagArgValue {
self.0.to_string().into_diag_arg(path)
}
}
impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> {
fn from(t: &'a dyn fmt::Display) -> Self {
DiagArgFromDisplay(t)
}
}
impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> {
fn from(t: &'a T) -> Self {
DiagArgFromDisplay(t)
}
}
impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
fn into_diag_arg(self, path: &mut LongTyPath) -> DiagArgValue {
self.clone().into_diag_arg(path)
}
}
#[macro_export]
macro_rules! into_diag_arg_using_display {
($( $ty:ty ),+ $(,)?) => {
$(
impl $crate::rustc_error_messages::IntoDiagArg for $ty {
fn into_diag_arg(self, path: &mut $crate::rustc_error_messages::LongTyPath) -> $crate::rustc_error_messages::DiagArgValue {
$crate::rustc_error_messages::ToString::to_string(&self).into_diag_arg(path)
}
}
)+
}
}
macro_rules! into_diag_arg_for_number {
($( $ty:ty ),+ $(,)?) => {
$(
impl $crate::rustc_error_messages::IntoDiagArg for $ty {
fn into_diag_arg(self, path: &mut $crate::rustc_error_messages::LongTyPath) -> $crate::rustc_error_messages::DiagArgValue {
#[allow(irrefutable_let_patterns)]
if let Ok(n) = TryInto::<i32>::try_into(self) {
$crate::rustc_error_messages::DiagArgValue::Number(n)
} else {
$crate::rustc_error_messages::ToString::to_string(&self).into_diag_arg(path)
}
}
}
)+
}
}
into_diag_arg_using_display!(
eko::file::Error,
core::fmt::Error,
Box<dyn core::error::Error>,
core::num::NonZero<u32>,
Edition,
crate::rustc_span::Ident,
crate::rustc_span::MacroRulesNormalizedIdent,
ParseIntError,
);
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
impl IntoDiagArg for bool {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
if self {
DiagArgValue::Str(Cow::Borrowed("true"))
} else {
DiagArgValue::Str(Cow::Borrowed("false"))
}
}
}
impl IntoDiagArg for char {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(format!("{self:?}")))
}
}
impl IntoDiagArg for Vec<char> {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::StrListSepByAnd(
self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
)
}
}
impl IntoDiagArg for crate::rustc_span::Symbol {
fn into_diag_arg(self, path: &mut LongTyPath) -> DiagArgValue {
self.to_ident_string().into_diag_arg(path)
}
}
impl<'a> IntoDiagArg for &'a str {
fn into_diag_arg(self, path: &mut LongTyPath) -> DiagArgValue {
self.to_string().into_diag_arg(path)
}
}
impl IntoDiagArg for String {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self))
}
}
impl<'a> IntoDiagArg for Cow<'a, str> {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self.into_owned()))
}
}
impl<'a> IntoDiagArg for &'a Path {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self.display().to_string()))
}
}
impl IntoDiagArg for PathBuf {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self.display().to_string()))
}
}
impl IntoDiagArg for alloc::ffi::CString {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
}
}
impl IntoDiagArg for crate::rustc_data_structures::small_c_str::SmallCStr {
fn into_diag_arg(self, _: &mut LongTyPath) -> DiagArgValue {
DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
}
}