fix(4.traits): реворк задания по парсеру #15
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
csit/pl-rust-2026!15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "github/fork/aragami3070/aragami3070/fix-4-traits-parser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Не уверен, что это хороший вариант, т.к. выходит много, возможно, слишком много. Но мб будет нормально, если какие-то моменты убрать или добавить бонус за задание или уже все хорошо и надо просто текст написать.
Хочу получить фидбэк до того как начну переписывать текст задания (и typst шаблон, пожалуйста 👉👈)
@nrydanovДа, шаблон нужно дорабатывать и возможно использование #task не самая лучшая идея, но нужен фидбэк и время, которого на следующей неделе не будет из-за большого количества дедлайнов по домашкам.
Это оверинжиниринг. У тебя фабрика парсеров точно не будет иметь больше одной реализации. Как следствие, сама абстракция не нужна.
Аналогично тут. Я могу представить Parser как трейт, но не понимаю как может быть несколько реализаций фабрики для парсеров файлов.
Почему это называется Errors, а не Error?
по-моему вместо этого можно #[derive(Debug)] сделать.
Почему не pub enum ParserError, где тип будет кодироваться как enum?
Тут TODO лучше написать внутри {} возле CsvParser и TsvParser
Давай задавать тут правильные ограничения. Если надо я потом уберу, а если задания сдадут с нужными ограничениями но не смогут объяснить почему — будет плохо)
Я подумал тут насчет итераторов и сейчас это выглядит плохо, потому что нам примерно никогда понадобится только часть данных из итератора (а это в основном то, из-за чего итераторы любят). Плюс такая сигнатура даст неочевидные ограничения на лайфтайм. Короче, плюсов не вижу, а вот минусы скорее да.
Лучше возвращать
Vec<Table>, в случае чего у него естьIntoIterator.По хорошему это надо смержить отдельно, мне трудно ревьюить, потому что diff — полное задание, а не только изменения самого задания.
Заметь, что в реальной разработке будут аналогичные проблемы. Нужно стараться, чтобы diff в точности отражал содержимое изменений.
Review: Changes requested
Правок много, думаю это не исчерпывающий список, но пока мы существующие проблемы не решим, будет трудно вносить правки дальше.
На Typst фидбек готов дать в рамках отдельного MR.
Но мне надо еще почитать про то, когда все-таки идиоматично возвращать итераторы. Пока не будем усложнять без четкого понимания зачем.
Я бы поспорил на эту тему, т.к. при парсинге одного файла тебе возвращается
Result<Table>=> у тбея будетVec<Result<Table>>, а неVec<Table>. АVec<Result<Table>>ты точно будешь как-то мапить или фильтровать, чтобы обработать всеResultи какой смысл тогда отVec?Ограничений на лайфтайм вообще нет и я не вижу откуда они могут здесь вылезти, обычное iter().map по path и все. Ограничения на лайфтайм будут в реализации кеширования парсеров, но оно вылезет и без возвращения итератора.
Единственный минус, который я пока что вижу - вариант с итератором ругается на todo! вместо возврата итератора, но это скорее повод открыть issue в репозитории rust-lang)
Из кеширования парсеров в
try_parse_fileвылезает, то что тебе придется убирать ограничения с трейтаParserи переносить их в метод трейта, а точнее делать через dyn. Поэтому либо кеширование парсеров - оверхед, либо указание вешать ограничения наParserзаставит переписывать трейт, когда человек дойдет до кеширования парсеров и не сможет сделать его именно с таким трейтом.Думаю стоит показать это в четверг на моей реализации. + там нет ничего мега сложного и на лекции по трейтам это объяснялось.
Да, ок. Просто в начале сема оговаривалось, что лучше не плодить много MR-ов и пихать все в один. Потом вынесу в отдельный, когда будет время.
А что за кэширование парсеров? зачем?
Первое: про лайфтаймы. Сейчас ты принимаешь paths: &[P] по ссылке, неявно там &'a [P]. Когда ты делаешь
paths.iter().map(...), ты создаешь итератор, который внутри себя захватил элементыpathsпо ссылке. Какой у нее будет лайфтайм? У нее, логично, будет 'a, поэтому у тебя по факту возвращаемый тип-> impl Iterator<Item = Result<Table, Errors>> + 'a. Это можно проверить так:Так что с лайфтаймами нюансы есть.
Одно популярное использование итераторов — это когда ты хочешь без лишних аллокаций получить какое-то удобное представление над данными (например, разбить на подстроки по пробелу и т.д). Но у тебя сейчас внутри итератора владеющие структуры, поэтому этот аргумент не валиден. И даже если ты сделаешь &str вместо String он тоже будет невалиден, потому что у тебя полученные строки в таблице не являются производными от входных данных. Можно мыслить так. Ты не трансформируешь напрямую входной поток, ты используешь данные на входе и дальше используешь внешний эффект (чтение данных).
Еще итераторы хороши когда ты хочешь написать программную абстракцию, которая хочет производить данные, но не хочет держать разом все данные в памяти. Если бы ты написал функцию, которая возвращает по одной конкретной строке из файла — я бы прикол понял. Возврат парсинга по одному файлу оправдать сложнее (лично мне), хотя тут я соглашусь, что все-таки логика тут присутствует.
Ну и кстати если ты возвращаешь в виде итератора чтение файлов, ты делаешь ленивую логику, в которой I/O операции будут размазаны на вызовы next(), что для вызывающего неочевидно и может быть некрасиво. В общем и целом, такое применение итераторов может создать студентам ложное ощущение, что так правильно, хотя на деле неочевидно зачем они нужны.
Короче, не все тут так просто.
Не помню, чтобы я говорил, что много MR — плохо. Я, наверное, говорил, что неточности и опечатки можно скопом вместе в 1 MR собирать, но переписывание typst в эту рамку вряд ли влезает.
Ну ты же сам говорил, что ты хочешь, чтобы у тебя не создавался парсер на каждый файл, а переиспользовался. Мы же чисто ради этого тогда про фабрику говорить начали.
Ты прав, было, но я не очень осознавал, что у нас у парсера похоже нет своего внутреннего состояния. А раз нет его, то структура весит 0 и непонятно что кэшировать :)
С последним пока не до конца переварил, но соглашусь, наверное это хороший аргумент, потом поправлю, но все таки на
Vec<Result<Table>>, а неVec<Table>.С лайфтаймом: я понимаю, что в твоем примере это может привести к проблемам, но в мой голове это не является проблемой, т.к. я не могу представить ситуацию где мне итератор нужен дольше чем входные данные.
restored source branch
github/fork/aragami3070/aragami3070/fix-4-traits-parserView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.