Советы начинающему

163 views
Skip to first unread message

Michael Pankov

unread,
Dec 19, 2014, 11:30:23 AM12/19/14
to rust-r...@googlegroups.com
Всем привет!

Я изучаю Rust и сделал маленькую библиотеку-обёртку над стандартным ящиком term. Библиотека нужна чтобы делать форматированный вывод размеченного текста на терминал - наподобие HTML:
  • ^bg(red)The ^fg(bright-black)text to ^bg(blue)^fg(cyan)colorize

Нужно это всё просто для удобство ввода-вывода в игре, которая работает в терминале и тоже написана на Rust ради изучения языка.

Суть в том, что я хотел бы попросить у более опытных товарищей посмотреть код с целью сделать его более понятным, идиоматичным и правильным.

Конкретно, мне нравится несколько моментов в существующем коде:

  1. Некоторые Token ы содержат в себе Option. Поэтому если пользователь хочет передавать в render кусок (slice) токенов, он может передать что-то с None и библиотека запаникует.
  2. Обработка ошибок сейчас практически отсутствует. Всё паникует если попадается некорректный поток токенов. Это, скорее всего, следствие пункта 1, но тем не менее.
  3. Распространение Result наверх, как в строке 287 - должен же быть идиоматичный способ сделать это?
  4. Итерирование - строки 63 и 237 - мне пришлось делать всю работу в вложенном блоке, потому что иначе проверка заимствований (borrow checker) не проходит (две изменяемые ссылки на iter). Мне кажется, должен быть способ лучше.
  5. Сопоставление с &Something - строка 245 - мне пришлось так делать опять же из-за проверки заимствований - она не давала двинуть значение из неизменяемого куска через итератор (move the value out of immutable slice via iterator). Я знаю, что предпочтительно сопоставлять с Something, но не понял как сделать это в данном случае.
  6. Меньшая проблема - это дублирование атрибутов. У меня те же атрибуты в Token что и в term::attr::*. Выглядит как ещё один результат пункта 1.

Если такой запрос на код-ревью не по адресу - прошу простить.

Сергей Прохоров

unread,
Dec 20, 2014, 4:42:08 AM12/20/14
to rust-r...@googlegroups.com
пятница, 19 декабря 2014 г., 19:30:23 UTC+3 пользователь Michael Pankov написал:
Всем привет!

Я изучаю Rust и сделал маленькую библиотеку-обёртку над стандартным ящиком term. Библиотека нужна чтобы делать форматированный вывод размеченного текста на терминал - наподобие HTML:
  • ^bg(red)The ^fg(bright-black)text to ^bg(blue)^fg(cyan)colorize

Нужно это всё просто для удобство ввода-вывода в игре, которая работает в терминале и тоже написана на Rust ради изучения языка.

Суть в том, что я хотел бы попросить у более опытных товарищей посмотреть код с целью сделать его более понятным, идиоматичным и правильным.

Конкретно, мне нравится несколько моментов в существующем коде:  

Некоторые Token ы содержат в себе Option. Поэтому если пользователь хочет передавать в render кусок (slice) токенов, он может передать что-то с None и библиотека запаникует.

Почему бы в этих случаях (Italic, Underline etc) не обрабатывать оба случая - some и none? Вообще, не совсем понятно почему там Some(bool)? 3 состояния возможно? Тогда может сделать под эти 3 состояния отдельный Enum(да, нет, не знаю)?
 
Обработка ошибок сейчас практически отсутствует. Всё паникует если попадается некорректный поток токенов. Это, скорее всего, следствие пункта 1, но тем не менее.
Распространение Result наверх, как в строке 287 - должен же быть идиоматичный способ сделать это?
Может макрос try!() ?
 let sure_tokens = try!(parse(s));
 
Ok(render(term, sure_tokens.as_slice()))
 

Итерирование - строки 63 и 237 - мне пришлось делать всю работу в вложенном блоке, потому что иначе проверка заимствований (borrow checker) не проходит (две изменяемые ссылки на iter). Мне кажется, должен быть способ лучше.
честно сказать, не понял, почему бы не написать просто
for n in s.chars(){ ... }

Michael Pankov

unread,
Dec 20, 2014, 10:12:09 AM12/20/14
to rust-r...@googlegroups.com
On Sat, Dec 20, 2014, at 12:42 PM, Сергей Прохоров wrote:
пятница, 19 декабря 2014 г., 19:30:23 UTC+3 пользователь Michael Pankov написал:
Всем привет!
 
Я изучаю Rust и сделал маленькую библиотеку-обёртку над стандартным ящиком term. Библиотека нужна чтобы делать форматированный вывод размеченного текста на терминал - наподобие HTML:
  • ^bg(red)The ^fg(bright-black)text to ^bg(blue)^fg(cyan)colorize

Нужно это всё просто для удобство ввода-вывода в игре, которая работает в терминале и тоже написана на Rust ради изучения языка.

Суть в том, что я хотел бы попросить у более опытных товарищей посмотреть код с целью сделать его более понятным, идиоматичным и правильным.

Конкретно, мне нравится несколько моментов в существующем коде:  

Некоторые Token ы содержат в себе Option. Поэтому если пользователь хочет передавать в render кусок (slice) токенов, он может передать что-то с None и библиотека запаникует.

Почему бы в этих случаях (Italic, Underline etc) не обрабатывать оба случая - some и none? Вообще, не совсем понятно почему там Some(bool)? 3 состояния возможно? Тогда может сделать под эти 3 состояния отдельный Enum(да, нет, не знаю)?
Обрабатывать None в принципе можно. Там Some(bool) потому что атрибуты вроде Italic принимают bool в term (t.attr(Italic(true))). Многие другие ничего не принимают, так как только включаются, а выключаются через t.reset(). 3 состояния не возможно. Ну и сам Option там сделан просто чтобы парсер bool а понимал куда этот bool девать.
 
Обработка ошибок сейчас практически отсутствует. Всё паникует если попадается некорректный поток токенов. Это, скорее всего, следствие пункта 1, но тем не менее.
Распространение Result наверх, как в строке 287 - должен же быть идиоматичный способ сделать это?
Может макрос try!() ?'
Вариант, спасибо

 let sure_tokens =try!(parse(s));
Ok(render(term, sure_tokens.as_slice()))

 
Итерирование - строки 63 и 237 - мне пришлось делать всю работу в вложенном блоке, потому что иначе проверка заимствований (borrow checker) не проходит (две изменяемые ссылки на iter). Мне кажется, должен быть способ лучше.
честно сказать, не понял, почему бы не написать просто
Так было в предыдущей версии. Потом оказалось, что мне нужно обнаруживать последнюю итерацию, чтобы засунуть current в Literal если текст кончился, или выдать ошибку если мы прервали разбор не дождавшись токена.
Reply all
Reply to author
Forward
0 new messages