✨ New type query function using TypeInfo
This commit is contained in:
parent
4b1e34487d
commit
5e457eed3d
8 changed files with 104 additions and 46 deletions
91
src/util.rs
91
src/util.rs
|
|
@ -5,25 +5,86 @@ use crate::trace;
|
|||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub enum TypeInfo {
|
||||
FullName,
|
||||
ShortName,
|
||||
NameFrom(isize),
|
||||
NameTo(isize),
|
||||
PartialName(isize, isize),
|
||||
}
|
||||
|
||||
impl TypeInfo {
|
||||
pub fn of<T: ?Sized>(&self) -> &'static str {
|
||||
let type_name = std::any::type_name::<T>();
|
||||
match self {
|
||||
TypeInfo::FullName => type_name,
|
||||
TypeInfo::ShortName => Self::partial(type_name, -1, None),
|
||||
TypeInfo::NameFrom(start) => Self::partial(type_name, *start, None),
|
||||
TypeInfo::NameTo(end) => Self::partial(type_name, 0, Some(*end)),
|
||||
TypeInfo::PartialName(start, end) => Self::partial(type_name, *start, Some(*end)),
|
||||
}
|
||||
}
|
||||
|
||||
fn partial(type_name: &'static str, start: isize, end: Option<isize>) -> &'static str {
|
||||
let maxlen = type_name.len();
|
||||
let mut segments = Vec::new();
|
||||
let mut segment_start = 0; // Start position of the current segment.
|
||||
let mut angle_brackets = 0; // Counter for tracking '<' and '>'.
|
||||
let mut previous_char = '\0'; // Initializes to a null character, no previous character.
|
||||
|
||||
for (idx, c) in type_name.char_indices() {
|
||||
match c {
|
||||
':' if angle_brackets == 0 => {
|
||||
if previous_char == ':' {
|
||||
if segment_start < idx - 1 {
|
||||
segments.push((segment_start, idx - 1)); // Do not include last '::'.
|
||||
}
|
||||
segment_start = idx + 1; // Next segment starts after '::'.
|
||||
}
|
||||
}
|
||||
'<' => angle_brackets += 1,
|
||||
'>' => angle_brackets -= 1,
|
||||
_ => {}
|
||||
}
|
||||
previous_char = c;
|
||||
}
|
||||
|
||||
// Include the last segment if there's any.
|
||||
if segment_start < maxlen {
|
||||
segments.push((segment_start, maxlen));
|
||||
}
|
||||
|
||||
// Calculates the start position.
|
||||
let start_pos = segments
|
||||
.get(if start >= 0 {
|
||||
start as usize
|
||||
} else {
|
||||
segments.len() - start.abs() as usize
|
||||
})
|
||||
.map_or(0, |&(s, _)| s);
|
||||
|
||||
// Calculates the end position.
|
||||
let end_pos = segments
|
||||
.get(if let Some(end) = end {
|
||||
if end >= 0 {
|
||||
end as usize
|
||||
} else {
|
||||
segments.len() - end.abs() as usize
|
||||
}
|
||||
} else {
|
||||
segments.len() - 1
|
||||
})
|
||||
.map_or(maxlen, |&(_, e)| e);
|
||||
|
||||
// Returns the partial string based on the calculated positions.
|
||||
&type_name[start_pos..end_pos]
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// FUNCTIONS HELPERS.
|
||||
// *************************************************************************************************
|
||||
|
||||
pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
|
||||
if last == 0 {
|
||||
return type_name;
|
||||
}
|
||||
let positions: Vec<_> = type_name.rmatch_indices("::").collect();
|
||||
if positions.len() < last {
|
||||
return type_name;
|
||||
}
|
||||
&type_name[(positions[last - 1].0 + 2)..]
|
||||
}
|
||||
|
||||
pub fn single_type_name<T: ?Sized>() -> &'static str {
|
||||
partial_type_name(std::any::type_name::<T>(), 1)
|
||||
}
|
||||
|
||||
pub fn absolute_dir(
|
||||
root_path: impl Into<String>,
|
||||
relative_path: impl Into<String>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue