// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
/// Trait for types whose elements can test for equality
pub(open) trait Eq {
fn equal(Self, Self) -> Bool
fn not_equal(Self, Self) -> Bool = _
}
///|
impl Eq with fn not_equal(x, y) {
!(x == y)
}
///|
/// Trait for types whose elements are ordered
///
/// The return value of [compare] is:
/// - zero, if the two arguments are equal
/// - negative, if the first argument is smaller
/// - positive, if the first argument is greater
pub(open) trait Compare: Eq {
fn compare(Self, Self) -> Int
fn op_lt(Self, Self) -> Bool = _
fn op_gt(Self, Self) -> Bool = _
fn op_le(Self, Self) -> Bool = _
fn op_ge(Self, Self) -> Bool = _
}
///|
impl Compare with fn op_lt(x, y) {
x.compare(y).is_neg()
}
///|
impl Compare with fn op_gt(x, y) {
x.compare(y).is_pos()
}
///|
impl Compare with fn op_le(x, y) {
x.compare(y).is_non_pos()
}
///|
impl Compare with fn op_ge(x, y) {
x.compare(y).is_non_neg()
}
///|
/// Trait for types that can be hashed
///
/// The `hash` method should return a hash value for the type, which is used in hash tables and other data structures.
/// The `hash_combine` method is used to combine the hash of the current value with another hash value,
/// typically used to hash composite types.
///
/// When two values are equal according to the `Eq` trait, they should produce the same hash value.
///
/// The `hash` method does not need to be implemented if `hash_combine` is implemented,
/// When implemented separately, `hash` **does not need** to produce a hash value that is consistent with `hash_combine`.
pub(open) trait Hash {
fn hash_combine(Self, Hasher) -> Unit
fn hash(Self) -> Int = _
}
///|
impl Hash with fn hash(self) {
let h = Hasher()
h.combine(self)
h.finalize()
}
///|
/// Trait for types with a default value
pub(open) trait Default {
fn default() -> Self
}
///|
/// Trait for append-only text sinks used by `Show` implementations.
///
/// A logger receives formatted output without requiring callers to allocate a
/// complete `String` first.
pub(open) trait Logger {
/// Writes a string to the logger.
fn write_string(Self, String) -> Unit = _
/// Writes a substring of the given string to the logger.
#deprecated("use `write_view` instead", skip_current_package=true)
fn write_substring(Self, String, Int, Int) -> Unit = _
/// Writes a string view to the logger.
fn write_view(Self, StringView) -> Unit = _
/// Writes a character to the logger.
fn write_char(Self, Char) -> Unit = _
fn write_string_interpolation(Self, &Show) -> Unit = _
fn write(Self, &Show) -> Unit = _
}
///|
impl Logger with fn write_string_interpolation(self, show) {
show.output(self)
}
///|
impl Logger with fn write(self, show) {
show.output(self)
}
///|
/// Writes a substring of the given string to the logger.
impl Logger with fn write_substring(self, value, start, len) {
self.write_view(value[start:start + len])
}
///|
/// Writes a string to the logger.
impl Logger with fn write_string(self, value) {
self.write_view(value)
}
///|
/// Writes a string view to the logger.
#deprecated("replace `impl write_substring` with `impl write_view`")
impl Logger with fn write_view(self, value) {
self.write_substring(value.data(), value.start_offset(), value.length())
}
///|
/// Writes a character to the logger.
impl Logger with fn write_char(self, value) {
self.write_string([value])
}
///|
/// Trait for types that can be converted to `String`
#must_implement_one(output, to_string)
pub(open) trait Show {
// `output` writes a string representation of `self` to a logger.
// The behaviors of output and to_string should be the same.
fn output(Self, &Logger) -> Unit = _
// `to_string` should be used by end users of `Show`,
// for printing, interpolation, etc. only, and should not be used for composition.
fn to_string(Self) -> String = _
}
///|
/// Default implementation for `Show::output`, uses `Show::to_string`.
impl Show with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
/// Default implementation for `Show::to_string`, uses a `StringBuilder`
impl Show with fn to_string(self) {
let logger = StringBuilder()
self.output(logger)
logger.to_string()
}
///|
/// Writes the `Show` representation of an object to the logger.
pub fn[Obj : Show] &Logger::write_object(self : &Logger, obj : Obj) -> Unit {
obj.output(self)
}
///|
/// Writes an iterator of `Show` values to the logger.
///
/// By default, values are written in list form, such as `[1, 2]`. The
/// `prefix`, `suffix`, and `sep` arguments customize the surrounding text and
/// separator. If `trailing` is true, `sep` is also written after the last value.
pub fn[T : Show] &Logger::write_iter(
self : &Logger,
iter : Iter[T],
prefix? : String = "[",
suffix? : String = "]",
sep? : String = ", ",
trailing? : Bool = false,
) -> Unit {
self.write_string(prefix)
if trailing {
for x in iter {
self.write_object(x)
self.write_string(sep)
}
} else if iter.next() is Some(x) {
self.write_object(x)
for x in iter {
self.write_string(sep)
self.write_object(x)
}
}
self.write_string(suffix)
}
// TODO: Logger::write_double(self:Logger, val:Double) -> Unit