Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
мда… оказали вы услугу rocket.rs, разместив ссылку на Хабре. В пятницу. Вечером.
Было бы неплохо добавить в статью и описание того как эти процедурные макросы работают,
а не только как их использовать.
Про Scala, к сожалению, ничего сказать не могу, но могу предположить, что scala-meta — это как раз аналог обычных макросов Rust, тогда как compile time reflection — аналог процедурных.О как же вы заблуждаетесь!
А еще serde умеет десериализовывать переменные окружения прямо в структуру, очень удобно.
Вообще, предоставлять средства сериализации для библиотечных типов это такой же хороший тон, как определять Debug и Display. Я думаю, в будущем это будет повсеместно.Это не выход. В той же scala, где генерация typeclass макросами используется давно и продуктивно, есть несколько различных библиотек для маршалинга в json. Думаю и в Rust появятся разные библиотеки для сходных задач — у всех свои фломастеры. К которой предоставлять имплементации? Ко всем?
impl Trait for Struct и все это импортируется в библиотеку C, которая уже используется где-то у вас в коде.#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct WorkspaceEdit {
/// Holds changes to existing resources.
#[serde(deserialize_with = "deserialize_url_map", serialize_with = "serialize_url_map")]
pub changes: HashMap<Url, Vec<TextEdit>>,
// changes: { [uri: string]: TextEdit[]; };
}
fn deserialize_url_map<D>(deserializer: D) -> Result<HashMap<Url, Vec<TextEdit>>, D::Error>
where D: serde::Deserializer
{
struct UrlMapVisitor;
impl de::Visitor for UrlMapVisitor {
type Value = HashMap<Url, Vec<TextEdit>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("map")
}
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
where M: de::MapVisitor
{
let mut values = HashMap::with_capacity(visitor.size_hint().0);
// While there are entries remaining in the input, add them
// into our map.
while let Some((key, value)) = visitor.visit::<url_serde::De<Url>, _>()? {
values.insert(key.into_inner(), value);
}
Ok(values)
}
}
// Instantiate our Visitor and ask the Deserializer to drive
// it over the input data, resulting in an instance of MyMap.
deserializer.deserialize_map(UrlMapVisitor)
}
fn serialize_url_map<S>(changes: &HashMap<Url, Vec<TextEdit>>,
serializer: S)
-> Result<S::Ok, S::Error>
where S: serde::Serializer
{
use serde::ser::SerializeMap;
let mut map = serializer.serialize_map(Some(changes.len()))?;
for (k, v) in changes {
map.serialize_key(k.as_str())?;
map.serialize_value(v)?;
}
map.end()
}
Свершилось! Процедурные макросы в Rust 1.15