hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

price.mojo (1874B)


      1 from std.collections import Optional
      2 
      3 
      4 @fieldwise_init
      5 struct Price(Copyable, Movable):
      6     var state: String
      7     var amount: Int
      8     var scale: Int
      9     var currency: String
     10     var basis: String
     11 
     12 
     13 def known_price(
     14     amount: Int, scale: Int, currency: String, basis: String
     15 ) raises -> Price:
     16     if scale < 0 or scale > 9:
     17         raise Error("price scale must be between 0 and 9")
     18     if currency.strip() == "":
     19         raise Error("known price requires a currency")
     20     if basis != "per_unit" and basis != "per_pack" and basis != "per_order":
     21         raise Error("price basis must be per_unit, per_pack or per_order")
     22     if amount < 0:
     23         raise Error("price amount must be non-negative")
     24     return Price(
     25         state="known",
     26         amount=amount,
     27         scale=scale,
     28         currency=String(currency),
     29         basis=String(basis),
     30     )
     31 
     32 
     33 def unknown_price() -> Price:
     34     return Price(
     35         state="unknown", amount=0, scale=0, currency="", basis="unknown"
     36     )
     37 
     38 
     39 def price_is_known(price: Price) -> Bool:
     40     return price.state == "known"
     41 
     42 
     43 def price_compare(left: Price, right: Price) raises -> Int:
     44     if not price_is_known(left) or not price_is_known(right):
     45         raise Error("cannot compare unknown prices")
     46     if left.currency != right.currency:
     47         raise Error(
     48             "cannot compare prices in different currencies without conversion"
     49         )
     50     if left.basis != right.basis:
     51         raise Error("cannot compare prices with different bases")
     52     var scale = left.scale if left.scale > right.scale else right.scale
     53     var left_value = left.amount
     54     var right_value = right.amount
     55     for _ in range(scale - left.scale):
     56         left_value *= 10
     57     for _ in range(scale - right.scale):
     58         right_value *= 10
     59     if left_value < right_value:
     60         return -1
     61     if left_value > right_value:
     62         return 1
     63     return 0