///|
struct Number(String) derive(Debug)

///|
pub impl Eq for Number with equal(a, b) {
  a.0 == b.0
}

///|
pub fn Number::from_int(value : Int) -> Number {
  Number(Int::to_string(value))
}

///|
pub fn Number::from_uint(value : UInt) -> Number {
  Number(UInt::to_string(value))
}

///|
pub fn Number::from_int64(value : Int64) -> Number {
  Number(Int64::to_string(value))
}

///|
pub fn Number::from_uint64(value : UInt64) -> Number {
  Number(UInt64::to_string(value))
}

///|
pub fn Number::from_float(value : Float) -> Number {
  Number(Double::to_string(value.to_double()))
}

///|
pub fn Number::from_double(value : Double) -> Number {
  Number(Double::to_string(value))
}

///|
pub fn Number::from_bigint(value : BigInt) -> Number {
  Number(BigInt::to_string(value))
}

///|
pub fn Number::to_double(
  self : Number,
  path? : JsonPath = Root,
) -> Double raise JsonDecodeError {
  @strconv.parse_double(self.0) catch {
    error =>
      raise JsonDecodeError(
        path~,
        "Number::to_double: parsing failure \{error}",
      )
  }
}

///|
pub fn Number::to_float(
  self : Number,
  path? : JsonPath = Root,
) -> Float raise JsonDecodeError {
  Float::from_double(@strconv.parse_double(self.0)) catch {
    error =>
      raise JsonDecodeError(path~, "Number::to_float: parsing failure \{error}")
  }
}

///|
pub fn Number::to_int64(
  self : Number,
  path? : JsonPath = Root,
) -> Int64 raise JsonDecodeError {
  @strconv.parse_int64(self.0) catch {
    error =>
      raise JsonDecodeError(path~, "Number::to_int64: parsing failure \{error}")
  }
}

///|
pub fn Number::to_uint64(
  self : Number,
  path? : JsonPath = Root,
) -> UInt64 raise JsonDecodeError {
  @strconv.parse_uint64(self.0) catch {
    error =>
      raise JsonDecodeError(
        path~,
        "Number::to_uint64: parsing failure \{error}",
      )
  }
}

///|
pub fn Number::to_int(
  self : Number,
  path? : JsonPath = Root,
) -> Int raise JsonDecodeError {
  @strconv.parse_int(self.0) catch {
    error =>
      raise JsonDecodeError(path~, "Number::to_int: parsing failure \{error}")
  }
}

///|
pub fn Number::to_uint(
  self : Number,
  path? : JsonPath = Root,
) -> UInt raise JsonDecodeError {
  @strconv.parse_uint(self.0) catch {
    error =>
      raise JsonDecodeError(path~, "Number::to_uint: parsing failure \{error}")
  }
}

///|
pub fn Number::to_string(self : Number) -> String {
  self.0
}