equi-ty 0.1.1

A crate to suggest (approx) equivalent types for a given type.
Documentation
from peewee import (
    CharField,
    IntegerField,
    ForeignKeyField,
    Check,
    Model,
    SqliteDatabase,
)

import utils

DB_PATH = utils.get_from_config("EQUITY_DB")
equity_db = SqliteDatabase(DB_PATH)


# THOUGHTS:
#
# Identify equivalent types:
# - member names + types
# - methods names + types (signature)
# - associated method names + types (signature)
# - implemented traits
# - generic args number + bounds
#
# Finding equivalent types in an *efficient* manner:
# - TODO
#
# Ranking the approximate types:
# - TODO


class BaseModel(Model):
    class Meta:
        database = equity_db
        legacy_table_names = False


class Crate(Model):
    name = CharField(null=False)
    version = CharField(null=False)

    class Meta:
        database = equity_db
        legacy_table_names = False
        indexes = ((("name", "version"), True),)


class Item(BaseModel):
    # the name of the item: e.g. HashMap
    name = CharField(null=False)

    # the crate where this item is defined in: e.g. std
    crate = ForeignKeyField(Crate, backref="items", on_delete="CASCADE")

    # the kind of the field: currently either 'Struct' or 'Enum'
    kind = CharField(
        choices=[
            ("Struct", "Struct"),
            ("TupleStruct", "TupleStruct"),
            ("Enum", "Enum"),
        ],
        constraints=[Check("kind IN ('Struct', 'TupleStruct', 'Enum')")],
        null=False,
    )

    # path where the item is defined: e.g. std::collections::hash::map::HashMap
    def_path = CharField(null=False)

    # public path used to import the item: e.g. std::collections::HashMap
    import_path = CharField(null=False)


# NOTE: for now we are only going with trait def_path as the identification of the trait.
# In future we may capture more details for traits, like we do for methods.
class Trait(BaseModel):
    name = CharField(null=False)
    def_path = CharField(null=False)


# many-to-many relationship between item <-> trait.
class Trait_Impl(BaseModel):
    item = ForeignKeyField(Item)
    trait = ForeignKeyField(Trait)


# NOTE: for now we are only going with method name, maybe we need to do better in future, by capturing args and return
# types as well.
class Method(BaseModel):
    name = CharField(null=False)
    item = ForeignKeyField(Item, backref="methods", on_delete="CASCADE")


class Associated_Method(BaseModel):
    name = CharField(null=False)
    item = ForeignKeyField(Item, backref="associated_methods", on_delete="CASCADE")


class Generic_Arg(BaseModel):
    # the index of this arg in the generics list
    arg_idx = IntegerField(null=False)
    item = ForeignKeyField(Item, backref="generics", on_delete="CASCADE")


class Generic_Arg_Bound(BaseModel):
    # desc of the trait in the bound
    bound = CharField(null=False)
    arg = ForeignKeyField(Generic_Arg, backref="bounds", on_delete="CASCADE")


# named so because compiler has a `VariantDef` for struct field / enum variant.
class Variant(BaseModel):
    name = CharField(null=False)

    # field / unnamed-field / variant
    kind = CharField(
        choices=[
            ("Field", "Field"),
            ("UnnamedField", "UnnamedField"),
            ("Variant", "Variant"),
        ],
        constraints=[Check("kind IN ('Field', 'UnnamedField', 'Variant')")],
        null=False,
    )

    # something like a kind_descr of rustc_middle::ty::Ty
    typ = CharField(null=False)

    # the item to which this variant belogns to (struct/enum)
    item = ForeignKeyField(Item, backref="variants", on_delete="CASCADE")