Вчера столкнулся с этими трейтами, стало интересно как они реализованы. По сути, это просто обвзяка вокруг стандартного &str. Но не могу понять, как они создаются.
Path::new создаётся всего лишь несколькими приведениями типов
OsStr и Path это таки не трейты, а обычные структуры.
Нет. В этом же и суть, что это платформозависимые типы, данные которых совсем не факт что могут быть представлены как стандартный str/String (допустим, путь с битым юникодом в str нельзя запихивать, но он может быть именем файла на некоторых платформах).
у него есть какое-то поле типа Slice, которое делает что угодно:
Надо смотреть исходники под конкретную платформу. Например, вот виндовая реализация:
Но не могу понять, как они создаются.
А в чем именно вопрос? Path, как ты указал, создается или на основе ссылки на что-то, представимое как OsStr, или из его “старшего брата” PathBuf.
OsStr аналогично - или на основе ссылки на какие-то данные (pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr), или заимствуется из своего “старшего брата” - OsString.
Вопрос в том, что поле inner в Path не инициализируется, а всё конструирование выполняется приведениями типов. И я что-то не вижу реализаций From<> или To<> для этих типов.
По сути, все создание OsStr живет в этих реализациях AsRef:
что поле inner в Path не инициализируется, а всё конструирование выполняется приведениями типов
Поскольку структура из одного поля, то адрес этого поля такой же, как у самой структуры. Так что в Path::new сначала через AsRef получается ссылка на OsStr, а потом она просто unsafe’ом приводится к ссылке на Path.