'How to make a primitive type parseable and printable differently? [duplicate]
I'm trying to create a new type, which will be i16, but print and parse differently:
use std::fmt;
use std::str::FromStr;
pub type Data = i16;
impl fmt::Display for Data {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "0x{:04X}", self)
}
}
impl FromStr for Data {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let hex: String = s.chars().skip(2).collect();
let d = Data::from_str_radix(&hex, 16)
.expect(&format!("Can't parse hex '{}' in '{}'", hex, s));
Ok(d)
}
}
#[test]
pub fn prints_itself() {
let data : Data = 42;
assert_eq!("0x003A", format!("{}", data));
}
#[test]
pub fn parses_itself() {
let data : Data = 42;
assert_eq!(data, "0x003A".parse());
}
It doesn't compile and I think I understand why. It seems I should declare my type Data somehow differently. How?
Solution 1:[1]
type Foo = Bar doesn't create a new type, it is a "type alias". You can think of it as if the compiler goes and checks for locations of Foo, and replaces them with Bar wherever it is used.
Instead, you want a new type: struct Foo(Bar) and implement any functions/traits you need on the new type.
This is a pretty common pattern, and I have written a library that takes some of the boilerplate out of it, though it is totally optional: https://crates.io/crates/microtype
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | cameron1024 |
