Я определяю API-интерфейс ящика в Rust stable (на данный момент, версия 1.2) и недоумеваю о лучших методах определения моих собственных типов, подобных строкам.
Например, у меня есть тип Foo
, который обертывает строку.
pub struct Foo(String);
Мой API скрывает конструкцию экземпляров Foo
, и, кроме того, поскольку поле кортежа является закрытым, приложение не может ошибочно построить недопустимое значение Foo
для себя. Это означает, что мой API ограничивает применение только действительными значениями Foo
. Пока все хорошо.
Тем не менее, я хочу, чтобы приложение могло использовать экземпляр Foo
, как будто это строка, скажем, печатая ее, записывая ее, записывая в файл, передавая ее в сторонний ящик, который принимает &str
, создавая копию с помощью to_string()
и мутируя копию и т.д. Короче говоря, я хочу, чтобы приложение могло "отбросить" Foo
-ness и работать со ссылкой на базовую строку. Поскольку приложение не может преобразовать исходную строку обратно в экземпляр Foo
, сохраняется безопасность типов.
Мой вопрос: какие признаки преобразования, если таковые имеются, должны реализовать мой ящик для Foo
, чтобы приложение "отбрасывало" Foo
-ness и работало с базовой строкой в виде необработанной строки? Важно, чтобы Foo
преобразовывался в &str
, чтобы исключить любое ненужное копирование базовой строки.
Например, как насчет?
impl AsRef<str> for Foo
Правильно ли это делать? Достаточно ли идиоматично? Есть ли какие-либо другие черты преобразования, которые я должен рассмотреть для реализации для Foo
?