Могу ли я использовать strum для преобразования строки в f64? - PullRequest
0 голосов
/ 12 ноября 2018

Я выполняю рефакторинг языка на основе малого стека Я написал и решил, что у меня будет фаза синтаксического анализатора, отделенная от фазы выполнения, и в результате я буду анализировать строки в перечислении Token. Я попытался использовать strum, чтобы сделать это, вот самый маленький пример, которым я мог управлять:

extern crate strum; // 0.11.0
#[macro_use]
extern crate strum_macros; // 0.11.0

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(f64)
}

fn main() {
}

По сути, это то, что нужно делать, если ничего не найдено, по умолчанию это парсинг. Итак, конвертируйте все, что дано, чтобы плавать в этом случае. Который дал:

error[E0277]: the trait bound `f64: std::convert::From<&str>` is not satisfied
 --> src/main.rs:5:10
  |
5 | #[derive(EnumString)]
  |          ^^^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `f64`
  |
  = help: the following implementations were found:
            <f64 as std::convert::From<u32>>
            <f64 as std::convert::From<i32>>
            <f64 as std::convert::From<f32>>
            <f64 as std::convert::From<i8>>
          and 3 others
  = note: required because of the requirements on the impl of `std::convert::Into<f64>` for `&str`

Я также попытался добавить impl для преобразования:

extern crate strum;
#[macro_use]
extern crate strum_macros;

impl<'a> From<&'a str> for f64 {
    #[inline]
    fn from(s: &'a str) -> Self {
        // See footnote [1] for why conversion is done this way.
        s.parse::<f64>().unwrap_or(0.0).to_owned();
    }
}

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(f64)
}

fn main() {
}

Однако это дает:

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
 --> src/main.rs:5:1
  |
5 | impl<'a> From<&'a str> for f64 {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
  |
  = note: the impl does not reference any types defined in this crate
  = note: define and implement a trait or new type instead

Поскольку я использую strum, я не мог поставить это на Rust Playground, но Cargo.toml:

[package]
name = "strum_test"
version = "0.1.0"

[dependencies]
strum = "0.11.0"
strum_macros = "0.11.0"

И файл, который я редактировал, был в strum_test/src/main.rs. Есть ли способ справиться с этим поведением в strum, или есть хотя бы еще один изящный способ обработать это преобразование из &str в enum Token?


1 В языке по замыслу должно быть сложно ошибиться. Имеет ли смысл конвертировать, например, "lol" в 0? Не совсем, но мой язык все равно это делает. Более подробная информация приведена в ссылке CodeReview.

1 Ответ

0 голосов
/ 13 ноября 2018

Исходя из комментария Свена Марнача, я добавил struct Float(f64). Вот весь код для справки:

extern crate strum;
#[macro_use]
extern crate strum_macros;

struct Float(f64);

impl<'a> From<&'a str> for Float {
    #[inline]
    fn from(s: &'a str) -> Self {
        Float(s.parse::<f64>().unwrap_or(0.0).to_owned())
    }
}

#[derive(EnumString)]
enum Token {
    #[strum(default="true")]
    Number(Float)
}

fn main() {
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...