Anton
https://gist.github.com/mexus/304ee9a3354ddb67649d10de0dd0a951
отлично, теперь я понял
Anton
спасибо!
Denys
@mexus @lundibundi @notplhk Таки сделал удаление ноды, без Rc и т.п. Как я и думал, эту проблему нужно было решать архитектурно. Написал новый рекурсивный метод, который вызывается из дерева, а потом делегирует ноде этого дерева. Вот коммит: https://github.com/AtomicInteger/one_more_dstruct/commit/3ebf051f47f9132727197ba22b6dedb0c8cde561
В мут парент бай вал лучше заюзать .iter().find тогда не нужно будет создавать новый ел дерева и копировать Не совсем понял зачем ты клонишь знач при ретейн в делет ноде? В делет валуе тоже &T я думаю Так же, ретейн как то сильно мощно для удаления одного знач как по мне, лучше заюзать итер.позитион.мап(ремув) или найтли remove_item, но тут прийдется создать ноду, а в пред просто поиск
Anton
Вобщем суть, если нужно просто свою ошибку вернуть юзать бэйл, если же нужно обработать std ошибку или еще какую левую, то заимплементить From<Error> и отматчить какую ошибку вернуть
Anton
теперь все прям понятно стало, збс
Andrey
bail!(x) это всего навсего return Err(x);
Anton
bail!(x) это всего навсего return Err(x);
такой варик у меня не компилился если в чистую возвращать
Anton
хотя может я где то в другом месте накосячил и поэтому не компилилось
Andrey
return Err(x.into())
Маjко
bail!(x) это всего навсего return Err(x);
Увы, нет. Это форматит ошибку и возвращает стрингу. Потом не сдаункастить до своей ошибки
Aleksey
Или return Err(x)?
Andrey
Увы, нет. Это форматит ошибку и возвращает стрингу. Потом не сдаункастить до своей ошибки
Ага. Ещё хуже. Этот bail! скопировали из error-chain и сделали несовместимым. Даже issue на это было.
Денис
Да, чё-то я с бейлом наверное перегнул, лучше уж return Err(...into())
Денис
Хотя ещё лучше возвращать failure::Error)
Денис
а, блин, into как раз и надо с failure::Error юзать
Денис
bail!() превращается в Error: ErrorMessage { msg: Variant1 }, .into() превращается в Error: Variant1
Rostyslav
В мут парент бай вал лучше заюзать .iter().find тогда не нужно будет создавать новый ел дерева и копировать Не совсем понял зачем ты клонишь знач при ретейн в делет ноде? В делет валуе тоже &T я думаю Так же, ретейн как то сильно мощно для удаления одного знач как по мне, лучше заюзать итер.позитион.мап(ремув) или найтли remove_item, но тут прийдется создать ноду, а в пред просто поиск
> лучше заюзать .iter().find Но, он ведь используется для получения найденной ноды, а мне нужно просто проверить, есть ли она. > Не совсем понял зачем ты клонишь знач при ретейн в делет ноде? Потому что внутри retain child - это ссылка, соотв. child.get_value() => cannot move out borrowed content. > В делет валуе тоже &T я думаю Оставил T, потому что при сравнении child.get_value().unwrap() != value value должно быть T. > лучше заюзать итер.позитион.мап(ремув) А в чём разница?
Rostyslav
Ну суть не в файле а в том что тебе не нужно создавать ноду каждый раз, можешь заюзать позитион или просто iter.any
.any да, это подходит.Только код превращается в это. Или можно лучше? Я просто на скорую руку накидал, и вот: if self.get_root().get_children().iter().any(|child| { child.get_value().clone().unwrap() == value.clone() }) { return self.get_mut_root(); }
Denys
Да вроде не, только этот клон все равно странно выглядит, надо как доберусь до компа глянуть что там
Денис
position возвращает номер элемента в массиве
Денис
fn position<P>(&mut self, predicate: P) -> Option<usize>
Denys
?
Denys
Screenshot (Apr 14, 2018 13:20:47)
Denys
Он возражает оптион юсайз
Denys
Это предикат бул возвр должен
Rostyslav
position возвращает номер элемента в массиве
Хм, я так и подумал и даже так и сделал, хоть иде подсказывает, что тот возвращает бул. Энивей, если запихнуть это всё вместе с предиктом внутрь ремува, код получается ужасным и я дальше не понимаю, в чём разница.
Денис
))
Rostyslav
Это предикат бул возвр должен
Ну, наверное я тогда не туда глянул.
Rostyslav
Ну, вот так он выглядит у меня, хз: let index = self.get_mut_parent_by_val(&value).get_mut_children().iter_mut().position(|child| { child.get_value().clone().unwrap() == value }).unwrap(); self.get_mut_parent_by_val(&value).get_mut_children().remove(index);
Rostyslav
Против: self.get_mut_parent_by_val(&value).get_mut_children().retain(|child| { child.get_value().clone().unwrap() != value });
Filipp
Клон анврап ради сравнения это сильно
Filipp
А выше вижу обсуждали уже
Rostyslav
В любом случае буду это рефакторить, для начала нужно что бы работало.
Anton
Посоны
Anton
новый микро тред тупых вопросов относительно десериализатора serde
Anton
собсно у меня есть json, и есть поля со значениями - но в некоторых полях есть возможность использовать несколько типов
Anton
ну типо может быть строка, и может быть объект
Денис
кстати, чё-то тут подумал, вместо return Err(MyEnumError::Variant1.into()); можно писать return Err(MyEnumError::Variant1)?;
Anton
и как бы нужно както обработать отдельно десериализатор, в некоторых местах
Anton
но писать с нуля имплементацию Deserializer
Anton
это ж enum в чистом виде
я хочу обойтись дектораторами
Денис
дык
Денис
а зачем?
Anton
тоесть по максимуму где можно чтобы он юзал только #derive[Deserealizer]
Денис
мне кажется проще сделать один енум и потом его конвертить во что нужно
Anton
но у меня есть хуйни где можно и строкой значение, и объектом
Денис
а самому Deserialize имплементить — это мне кажется хуже смерти
պլհկ
Читай главу enum representation в доке серде
Денис
ага, вот эту https://serde.rs/enum-representations.html
Anton
мне кажется проще сделать один енум и потом его конвертить во что нужно
ну смотри пример: { transform: [ { type: "rotate", value: "90", value_type: "deg" }, // Или "rotate(90deg)" ] }
Anton
автоматический десериализатор позволит только объектное значение первого типа
Денис
то если или объект или строка, так?
Денис
ща
Anton
но если строка - я бы хотел чтобы у меня была возможность самому настроить какое значение вернуть
Anton
и чтобы если это была строка, был другой обработчик
Маjко
Зачем так?
Anton
Зачем так?
упрощение в некоторых местах нужно, иначе слишком дохуя строк кода будет, так что в двух вариантах чтоб было
Маjко
Нет, ты не понял Зачем 2 варианта?
Anton
ну я пример привел
Anton
у меня есть свойства
պլհկ
serde(untagged) /thread
Anton
которые при стандартном десеализаторе требуют дохуя кода писать для json
պլհկ
Че за дохуя кода-то
Anton
в то время как я бы мог получить Value и все отдельно для разных типов обработать
Anton
Че за дохуя кода-то
бля, ну давай более реалистичный пример, градиенты. У меня градиент может быть просто объектом - в котором я пишу только начальный и финальный цвет с позицией, а может быть массивом, в котором у меня перечисляются все стоп поинты.
Anton
И мне нужно чтобы была возможность для отдельных типов полей самому заимплементить поведение десериализации из Value объекта
պլհկ
У тебя енум из 2 вариантов
Anton
т.е ты хочешь сказать что лучше для значения просто сделать енум?
Anton
Ну типо enum BackgroundGradient { Arr(...), Obj(...) }
Anton
и там проставить типы?
Anton
ну так выходной тип то все равно один получается
Anton
я думал есть возможность сделать типо имплементацию какого простого трейта, для того чтобы обработать json enum Value и возвратить значение уже готовое
պլհկ
enum Gradient { Simple(SimpleGradient), Complex(Vec<Point>) }