examples/advanced/13_traits.cat
# Exemple 13 : Traits

print("⇒ Trait basique avec methode")

trait Printable {
    repr(self) => { "printable" }
}

struct Tag implements(Printable) { name }

t = Tag("hello")
print("t.repr() =", t.repr())

print("\n⇒ Methode de trait accede a self")

trait HasArea {
    area(self) => { self.w * self.h }
}

struct Rect implements(HasArea) { w, h }

r = Rect(3, 4)
print("Rect(3, 4).area() =", r.area())

print("\n⇒ Heritage de trait (extends)")

trait Named {
    name(self) => { "anonymous" }
}

trait Greeter extends(Named) {
    greet(self) => { "hello" }
}

struct Bot implements(Greeter) {
    label
    name(self) => { self.label }
}

b = Bot("R2")
print("Bot('R2').greet() =", b.greet())
print("Bot('R2').name() =", b.name())

print("\n⇒ Override de methode par le struct")

trait DefaultValue {
    value(self) => { 10 }
}

struct Custom implements(DefaultValue) {
    x
    value(self) => { self.x * 2 }
}

print("Custom(7).value() =", Custom(7).value())

print("\n⇒ Plusieurs traits sans conflit")

trait Movable {
    move(self) => { "moving" }
}

trait Drawable {
    draw(self) => { "drawing" }
}

struct Sprite implements(Movable, Drawable) { id }

s = Sprite(1)
print("s.move() =", s.move())
print("s.draw() =", s.draw())

print("\n⇒ Conflit resolu par override")

trait X { f(self) => { 1 } }
trait Y { f(self) => { 2 } }

struct Resolved implements(X, Y) {
    f(self) => { 3 }
}

print("Resolved().f() =", Resolved().f())

print("\n⇒ Diamond (dedupe silencieux)")

trait Base { m(self) => { 0 } }
trait Left extends(Base) { }
trait Right extends(Base) { }

struct Diamond implements(Left, Right) { }

print("Diamond().m() =", Diamond().m())

print("\n⇒ Trait avec corps vide")

trait Marker { }

struct Tagged implements(Marker) { label }

print("Tagged('ok') =", Tagged("ok"))

print("\n⇒ Abstract methods dans les traits")

trait Serializable {
    @abstract serialize(self)
    to_json(self) => { "{" + self.serialize() + "}" }
}

struct Config implements(Serializable) {
    key, value
    serialize(self) => { f"{self.key}: {self.value}" }
}

cfg = Config("debug", True)
print("cfg.serialize() =", cfg.serialize())
print("cfg.to_json() =", cfg.to_json())

print("\n⇒ Static methods dans les traits")

trait Factory {
    @static
    create() => { "default" }
}

struct Widget implements(Factory) { v }

print("Widget.create() =", Widget.create())

print("\n⇒ Abstract static dans un trait")

trait Buildable {
    @abstract
    @static
    build()
}

struct Thing implements(Buildable) {
    x

    @static
    build() => { Thing(99) }
}

print("Thing.build().x =", Thing.build().x)