В тестировании на расте нет никаких граблей, правда не хочу разбрасывать тестовый код где попало так что только в контроллерах и одном, специально огороженном, хранилище констант. Что бы через полгода не гадать где все искать. Ошибки при падении надо бы облагородить немного, но пока хватит красить забор, накатаю еще эндпоинт.
В итоге в хэловорде будут сосуществовать ручные маппинги и авто, где что. Пойдет. Для всех моделей буду сразу писать сериализатор и обратно. Серде атрибутов хватает для этого почти всегда и писанины не так и много...хотя идеал когда нет, конечно. Запилю инфру под тестирование в ближайшее время полностью. Попробую придерживаться растовой традиции смешивания кода и тестов...хочется еще бэктрейсы в падения добавить.
deserializable_struct!(PublicKeyPem, String, "String");
Красивее не вышло, стринг надо два раза писать.
Так что типы будут жирные по тексту, а не автомат.
#[derive(Debug, Serialize, Deserialize)]
#[serde(from = "String")]
pub struct PreferredUsername(pub String);
impl std::ops::Deref for PreferredUsername {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<String> for PreferredUsername {
fn from(value: String) -> Self {
PreferredUsername(value)
}
}
Может я просто пока что то не понимаю.
Оказывается таки да, рускулайт серде не поддерживает кортежные структуры, там имен полей нет, но почему не поддерживает их в качестве значений, загадка. Нашел самое короткое решение
#[serde(from = "String")]
В итоге можно совсем мало потом написать, реализовать From<String> и много гетов можно не писать. При этом если тип внешний то можно десериализатор накатать все же. Это самое короткое, что можно так как для серде тоже надо. Короче увы нет решения кажется.
Главное, что меня раздражает это писать геты если руками и не автоматическая десериализация кортежных структур если с серде. Но второе менее неприятно, а может и решаемо. Идеал конечно автогенерация, но не нашел пока. Так что кажется лучшее, что есть это serde-rusqlite+refinery. Так как порожает меньше всего геморроя. В качестве автогенератора слоя примитивных моделей будет чатгопота, а далее компайл тайм во все поля...попробую.
Get опять же писать не надо, проблема в том, что автомапинги не времени компиляции, что неприятно.
Наверное все же попробую еще слой моделей для простой десериализации завести, автоматической, а из них уже собирать сложные внутренние. Хочется странного.
В итоге оказалось самое удобное просто все руками написать вместо автомаппингов, так как это просто надежнее и короче. Обычные запросы с именованными параметрами и обычные маппинги руками, либо придется городить вагон десериализаторов или промежуточных моделей. Не то что бы где-то по другому, но была надежда, что newtype хотя бы оно само проглотит, а оно не смогло это делать без доп пометок...что возня и не надо, так как тогда просто руками.
В итоге я так и не нашел удобного метода для кэшированного варианта, пришлось написать свой и юзать
pub fn get_user(username: &str) -> Result<UserDb> {
let conn = DB_POOL.get_connection()?;
let mut prepared = conn.prepare_cached(sql_fabric::get_user_sql())?;
get_single_entity(&mut prepared, params![username], from_row::<UserDb>)
.context("get user error")
}
а для не кэшированого он есть :)
Теперь надо кэширование стейтментов наладить, там методы капец неудобные как раз в связи с конвертацией ошибок.
Медитирую, недавно впервые играл в d&d, люблю смотреть научпоп лекции в ютубе, гулять. По субботам хожу в баню потом сижу в кондитерской и читаю. Обожаю музеи современного искусства и особенно импрессионистов. Предпочту посидеть у озера и посмотреть на горы. Этот инстанс мой. Еще есть канал https://youtube.com/@user-tc9eq9pz2q?si=uPmChHjU3UyZIDET
Политическая платформа - гороскопианец в рамках метакратии
Религия - вера в макаронного монстра
Космополит безродный.
Местоимение они/их, царь я или не царь!?