-
-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace DisplayAsDisplay and PathAsDisplay with AsDisplay trait
Rather than having separate traits implementing as_display method, replace DisplayAsDisplay and PathAsDisplay traits with a AsDisplay trait. The difference between those two traits is in the result returned by the as_display method. With AsDisplay trait this is captured by an associated type. The main motivation for the change is making it simpler to support no_std builds in the future. Previously, PathAsDisplay would have to be handled specially in such builds on the side of macro expansion. Now, thiserror-impl doesn’t need to be aware of any complications around AsDisplay since they are all contained in thiserror crate.
- Loading branch information
Showing
4 changed files
with
56 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,55 @@ | ||
use std::fmt::Display; | ||
use std::path::{self, Path, PathBuf}; | ||
use std::path::{Path, PathBuf}; | ||
|
||
#[doc(hidden)] | ||
pub trait DisplayAsDisplay { | ||
fn as_display(&self) -> Self; | ||
pub trait AsDisplay { | ||
type Target: Display + ?Sized; | ||
|
||
fn as_display(&self) -> &Self::Target; | ||
} | ||
|
||
impl<T: Display> DisplayAsDisplay for &T { | ||
fn as_display(&self) -> Self { | ||
impl<T: Display> AsDisplay for &T { | ||
type Target = T; | ||
|
||
fn as_display(&self) -> &Self::Target { | ||
self | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
pub trait PathAsDisplay { | ||
fn as_display(&self) -> path::Display<'_>; | ||
impl AsDisplay for Path { | ||
type Target = PathDisplay; | ||
|
||
#[inline] | ||
fn as_display(&self) -> &Self::Target { | ||
PathDisplay::new(self) | ||
} | ||
} | ||
|
||
impl PathAsDisplay for Path { | ||
fn as_display(&self) -> path::Display<'_> { | ||
self.display() | ||
impl AsDisplay for PathBuf { | ||
type Target = PathDisplay; | ||
|
||
#[inline] | ||
fn as_display(&self) -> &Self::Target { | ||
PathDisplay::new(self.as_path()) | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
#[repr(transparent)] | ||
pub struct PathDisplay(Path); | ||
|
||
impl PathDisplay { | ||
#[inline] | ||
fn new(path: &Path) -> &Self { | ||
// SAFETY: PathDisplay is repr(transparent) so casting pointers between | ||
// it and its payload is safe. | ||
unsafe { &*(path as *const Path as *const Self) } | ||
} | ||
} | ||
|
||
impl PathAsDisplay for PathBuf { | ||
fn as_display(&self) -> path::Display<'_> { | ||
self.display() | ||
impl Display for PathDisplay { | ||
#[inline] | ||
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
self.0.display().fmt(fmtr) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters