OxL Справочник OxL
РусскийEnglish

v3_types.oxl

oxl✓ проверяется в CI
@derive(Copy, Eq, Ord, Hash, Show)
pub(api) data Money { minor: i64 }

impl Money {
  pub const ZERO: Money = Money{ minor: 0 }
  static fn rub(r: i64) -> Money => Money{ minor: r * 100 }
  static fn zero() -> Money => Money.ZERO
  static op +(a: Money, b: Money) -> Money => Money{ minor: a.minor + b.minor }
  static op -(a: Money, b: Money) -> Money => Money{ minor: a.minor - b.minor }
  static op *(a: Money, k: i64) -> Money => Money{ minor: a.minor * k }
  static op /(a: Money, k: i64) -> Money => Money{ minor: a.minor / k }
}

interface Priced { fn price() -> Money }

type Sku = distinct str
data Product { sku: Sku; title: str; base: Money }
impl Product {
  open fn price() -> Money => base
}

type Percent = u8 where 0..=90

@sealed data Discounted {
  embed Product
  percent: Percent
}
impl Discounted {
  init of(p: Product, percent: u8) -> Self | InvalidValue =>
    Self{ Product: p, percent: Percent.from(percent)? }
  override fn price() -> Money => super.price() - super.price() * (percent as i64) / 100
}

fn total(items: List<dyn Priced>) -> Money  pure =>
  items.fold(Money.ZERO, (acc, i) => acc + i.price())

fn main() -> () | InvalidValue  io {
  let book = Product{ sku: Sku("b1"), title: "Book", base: Money.rub(1000) }
  let d = Discounted.of(book, 15)?
  assert d.price() == Money.rub(850)
  print("ok {d.price().minor}")
}

Скачать

Исходник: examples/v3_types.oxl