Skip to content

Django / GORM exporter 완결성 보완 - #169

Open
2heunxun wants to merge 54 commits into
dev-five-git:mainfrom
2heunxun:main
Open

Django / GORM exporter 완결성 보완#169
2heunxun wants to merge 54 commits into
dev-five-git:mainfrom
2heunxun:main

Conversation

@2heunxun

Copy link
Copy Markdown

요약

Django, GORM exporter를 검토해서 발견한 부족한 점 7가지를 전부 구현했습니다.
관계(FK) 코드생성이 두 백엔드에서 부분적으로만 지원되고 있었고, 공유 테스트
스위트에도 편입돼 있지 않았습니다. 이번 작업으로 두 백엔드를 나머지 4개
ORM(SeaORM/SQLAlchemy/SQLModel/JPA)과 동등한 수준으로 끌어올렸습니다.

변경 사항

  1. Django M2M 정션 테이블 인식 — 복합 PK + FK 2개 이상인 정션 테이블을
    감지해서 ManyToManyField(..., through=...)를 양쪽에 생성. 기존에는
    스키마 컨텍스트를 아예 무시하고 있었음.
  2. Django/GORM 복합(다중 컬럼) FK 지원 — GORM은 실제 관계 필드로
    (foreignKey:...;references:...), Django는 네이티브 지원이 없어서 주석으로
    관계 정보를 남기도록 처리 (기존엔 컬럼만 남고 관계 정보가 조용히 사라짐).
  3. GORM 자기참조 FK 버그 수정 — 계층구조 스키마(parent_id 같은)에서
    역방향(has-many) 관계가 아예 생성되지 않던 버그 발견 및 수정.
  4. Django/GORM을 공유 cross-ORM 스냅샷 스위트에 편입 — 기존엔 4개 ORM만
    공유 테스트로 교차검증되고 있었음. 편입 과정에서 Django의 실제 버그 2개를
    추가로 발견:
    • 인식 못 하는 SQL 상수 default가 정의되지 않은 Python 이름으로 그대로
      출력되던 문제 (import 시점에 크래시)
    • auto-increment PK 컬럼에 primary_key=True가 누락되던 문제 (Django
      자체 시스템 체크(fields.E100)에 걸림 — auto PK를 쓰는 거의 모든
      스키마에 영향)
  5. DjangoConfig / GormConfig 설정 섹션 추가vespertide.json에서
    Django app_label, GORM package_name을 커스터마이징할 수 있도록 지원
    (기존엔 SeaORM만 이런 설정 진입점이 있었음).
  6. Django clean_export_dir 회귀 테스트 추가 — 다른 ORM들은 다 있었는데
    Django만 빠져 있었음.
  7. 문서 업데이트 — README/AGENTS.md에 JPA/GORM/Django 반영 (GORM은
    머지된 지 오래됐는데도 문서에 전혀 언급이 안 되고 있었음).
  8. (추가 발견) Django 복합 PK 표현 버그 — 위 작업을 다 마친 뒤 Django를
    다른 5개 백엔드와 다시 비교 검토하다 발견. 복합 PK 테이블에서 어떤
    필드에도 primary_key=True가 안 붙고 Meta에도 아무 표시가 없어서,
    Django가 자체적으로 엉뚱한 auto id PK를 암묵적으로 추가해버리는
    문제였음 (실제 DB의 PK와 전혀 안 맞음). GORM/SeaORM은 둘 다 이미 제대로
    처리하고 있어서 비교하다 바로 드러남. Django 5.2+ 의 네이티브
    pk = models.CompositePrimaryKey(...)로 수정.

커버리지

위 작업 도중 실제 coverage 회귀(99.92%)가 발생한 걸 CI 실패로 확인하고,
Docker로 CI와 동일한 환경(특수 rustfmt 설정 + RUST_TEST_THREADS=1 +
PROPTEST_CASES=1024)을 재현해서 정밀 진단 후 전부 수정했습니다.
최종적으로 로컬 재현 환경에서 100.00% (12234/12234 lines) 확인.

검증

  • cargo test --workspace 전체 통과
  • cargo clippy --workspace -- -D warnings 클린
  • cargo fmt --all --check 클린
  • scripts/check-line-budget.sh 통과
  • cargo tarpaulin --engine llvm --fail-under 100 — 100% (Docker로 CI 환경
    동일 재현하여 확인)
  • CI 실제 실행 결과: coverage 포함 전 항목 통과 (codecov 업로드만 별도
    CODECOV_TOKEN 미설정 이슈로 실패 — 코드와 무관)

2heunxun and others added 30 commits May 16, 2026 19:04
Conflict resolution: kept GORM exporter support added in fork
while integrating upstream's 0.2.0 API changes, LSP features,
newtype identifiers, and refactored test structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds tests for all branches identified as uncovered (59 lines):
- Django: SmallAutoField, BigAutoField, Macaddr, Numeric, Custom type,
  UUID functional default, export() multi-table, nullable FK with db_column
- GORM: conflicting enum qualified names, Char type tag, FK relation field
  name collision, reverse relation disambiguation (two FKs same target)
- CLI: OrmArg::Django mapping, build_output_path Gorm .go extension,
  clean_export_dir Gorm .go cleanup

Also removes the erroneous targets line from rust-toolchain.toml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `cache-key: no-musl` to every `setup-rust-toolchain@v1` step that
does not already specify an explicit cross-compilation target.  This
changes the Rust toolchain cache key so that the previous cache (written
when rust-toolchain.toml briefly had `targets = ["x86_64-unknown-linux-musl"]`)
is not restored, eliminating the recurring
"override toolchain 'stable-x86_64-unknown-linux-musl' is not installed" error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sea-orm v2.0.0-rc.42 drops its dependency on ouroboros v0.18.5 (and
aliasable, id-arena). ouroboros has a RUSTSEC advisory for unsound
self-referential structs; without an explicit ignore entry in deny.toml
the cargo-deny CI gate was flagging it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…h 100%

Django: build_default Bool(false) and functional-default-on-non-special-type
branches; reference_action_str Restrict/SetDefault/NoAction arms; column
comment rendering; unnamed Index and unnamed composite UniqueConstraint in
Meta; to_pascal_case None arm via double-underscore input.

GORM: Numeric column (add_column_type, build_gorm_tag, decimal import);
unnamed and named Index (collect_index_info body + build_gorm_tag loop);
auto-named composite unique (collect_composite_unique_info None closure);
singular source-table plural (find_reverse_relations format!("{pascal}s"));
FK on_update body + nullable FK pointer type (render_fk_relation_field);
reference_action_str SetNull/SetDefault/NoAction; to_pascal_case None arm
via double-underscore table name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…enerator

arb_default_string() could produce reserved words like "in" as bare SQL
DEFAULT expressions, causing pg_query to reject the emitted CREATE TABLE
with "syntax error at or near 'in'". Added is_pg_reserved_keyword() (full
PG 17 §C.1 Type-A list) and a prop_filter on the bare-ident branch so the
strategy only generates non-reserved identifiers as unquoted defaults.

Also fixes fmt issues in the coverage tests added in the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- erd: add test for inline FK referencing absent parent table, covering
  the None early-return branch of inline_foreign_key_relation
- gorm/django: convert single-expression #[cfg(not(tarpaulin_include))]
  arms to block form so tarpaulin's source-level exclusion correctly
  identifies and skips the non_exhaustive future-variant guards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bution

erd: normalize_tables' map(closure).collect() becomes an explicit for loop
(the map closure was the same LLVM source-coverage attribution blind spot
documented in this crate's AGENTS.md; the prior fix only made the inner
with_context closure eager but left the outer map closure in place).

django: replace the enum max_length iterator chain (map(String::len).max())
with an explicit loop, and fold the single-statement primary_key/unique
kwargs into a for-loop over conditions instead of standalone trivial ifs.

gorm: render_enum's match was the last statement of a unit-returning
function; convert to sequential if let with an early return so the function
body ends on a plain statement instead of a match tail-expression.

All three spots are proven to execute today (existing snapshots already show
unique=True, max_length=9, and rendered enum consts), so this is a pure
coverage-attribution fix with no behavior change — snapshots are byte-identical
and all local build/test/clippy/fmt checks pass. Local tarpaulin isn't
runnable on Windows, so the 100% gate result is confirmed by CI on push.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diagnosed via a local tarpaulin run (Docker, same xd009642/tarpaulin
container CI uses) inspecting raw LLVM coverage regions instead of
guessing from reformatted line numbers. Each of the 5 previously-uncovered
lines had a distinct, verified cause:

- erd: normalize_tables' `?` error-propagation branch was never exercised
  by any test (all existing tests only feed valid tables). Added a test
  with a malformed inline FK reference to trigger normalize()'s Err path.
- erd: collect_foreign_key_relations' table-level FK `let-else { continue }`
  branch (absent referenced table) was untested — only the *inline* FK
  equivalent had a test (from 584b04b). Added the table-level counterpart.
- django: build_default's Bool(true) path was never tested (only
  Bool(false) was). Added test_bool_true_default.
- django: build_default's `return match { guarded-arm => {...} }` construct
  had a proven LLVM gap-region artifact on the match/guard header lines
  (arm bodies demonstrably execute via existing tests, e.g.
  test_server_default_timezone). Restructured into plain if-chains.
- gorm: render_enum's trailing if-let block's closing brace showed 0 hits
  despite its body executing (same gap-region artifact); restructured to
  collect into a Vec and lines.extend() it as a genuine trailing statement.
- gorm: go_base_type's ComplexColumnType::Enum arm was genuinely dead code
  (its only caller, go_type_for_column_mapped, already intercepts Enum
  before ever calling go_base_type) — removed.

Verified locally end-to-end: cargo tarpaulin --engine llvm against the
exact CI container reports erd/mod.rs 212/212, django/types.rs 94/94,
gorm/mod.rs 289/289 (100% each), with no other regressions across either
crate. cargo build/test/clippy/fmt and the line-budget check all pass on
the real (normally-formatted) source.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CI fmt job flagged these two spots as unformatted (from 510e868); rustfmt
--check now passes locally with no other diffs.
…hema

DjangoExporter previously fell back to the OrmExporter trait's default
render_entity_with_schema (schema-context ignored), so composite-PK
junction tables never produced a ManyToManyField on either side. Detect
2-FK junction tables (mirroring the SeaORM junction-detection pattern)
and emit ManyToManyField(..., through=..., related_name="+") for both
sides, with _via_<junction> disambiguation when multiple junctions link
the same pair of tables. Purely self-referential junctions are skipped
rather than guessed at.
Both exporters only recognized single-column FKs (columns.len() == 1),
so composite FKs silently dropped to plain scalar columns with no
relation info at all.

- GORM: composite FKs are a genuine native feature (comma-separated
  foreignKey/references tags), so emit a real belongs-to relation field,
  with numeric-suffix disambiguation on field-name collisions.
- Django: there is no native multi-column FK field, so emit a comment
  documenting the relationship instead of silently dropping it; the
  underlying columns still render normally and referential integrity is
  enforced by the generated database schema. Reuses the existing
  crate::utils::python::collect_composite_fks helper already shared with
  SQLAlchemy.
find_reverse_relations() skipped any "other" table equal to the current
table name, which meant a self-referencing FK (e.g. categories.parent_id
-> categories.id) only ever produced the forward belongs-to relation
("Parent"), never the reverse has-many ("Children"). The forward FK and
reverse-scan loop are independent, so the skip was unconditionally
dropping half of every self-referential relationship.

Removed the skip and special-cased self-ref naming to "Children" instead
of a pluralized table name (which would otherwise collide with the
struct's own name). Added regression tests for both directions, split
into gorm/tests/relations.rs (composite-FK + self-ref tests) to keep
gorm/tests/mod.rs under the 1200-line test-file budget.
… suite

Extends orm_cases! (60 fixtures) and render_entity_with_schema_snapshots
(14 relation-heavy scenarios) to render through Gorm/Django alongside the
existing 4 ORMs, matching the project's "every scenario cross-compared
across all ORMs" convention. Adds 120 new baseline snapshots; all render
successfully with no panics.

Reviewing the new baselines surfaced two real, pre-existing Django
correctness bugs (never caught because Django had zero cross-ORM fixture
coverage before this):

1. build_default()'s final fallback emitted unrecognized SQL constants
   verbatim as a bare Python identifier (e.g. `default=SOME_CONSTANT`),
   which is an undefined name and would crash at Django import time. Now
   omits the default unless it parses as a numeric literal.
2. Any auto-increment primary key (AutoField/SmallAutoField/BigAutoField)
   was rendered WITHOUT `primary_key=True` on the assumption that the
   Auto*Field type alone implies it — it does not. Django's own system
   checks (fields.E100) reject an explicit AutoField without
   primary_key=True, so every auto-PK schema this exporter has ever
   produced was invalid at `manage.py check`. Fixed by always emitting
   primary_key=True when the column is the (non-composite) PK; removed
   the now-dead is_auto_field() helper and the auto_increment parameter
   it existed solely to feed.
Django and GORM had no vespertide.json config surface at all, unlike
SeaOrmConfig. Adds two minimal, well-scoped knobs mirroring
SeaOrmExporterWithConfig's existing pattern:

- DjangoConfig.app_label: optional explicit `app_label` written into
  every generated model's Meta class, for projects where models don't
  live inside a standard Django app package (Django can't infer the
  label there). Omitted from Meta and from JSON when None.
- GormConfig.package_name: Go package name emitted at the top of every
  file (`package <name>`), default "models".

Both structs are #[non_exhaustive] and threaded through new
DjangoExporterWithConfig / GormExporterWithConfig wrappers, wired into
the CLI's cmd_export alongside the existing SeaOrmExporterWithConfig
special-case. Regenerated schemas/config.schema.json (schema-drift CI
gate) to include the two new sections.
SeaOrm/SqlAlchemy/SqlModel/Jpa/Gorm each had a dedicated
clean_export_dir_removes_*_for_* test; Django was the only export
target without one, even though it shares the .py cleanup path with
SqlAlchemy/SqlModel.
@owjs3901
owjs3901 self-requested a review July 26, 2026 13:11

@owjs3901 owjs3901 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CICD파일을 변경할 이유가 없습니다
.idea 폴더를 추가할 이유가 없습니다

Comment thread apps/landing/src/app/_components/code-tabs.tsx Outdated
Comment thread apps/landing/src/app/_components/copy-install.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment thread apps/landing/src/app/page.tsx Outdated
Comment on lines +8 to +17
@Entity
@Table(name = "users")
public class Users {

@Id
@Column(name = "id")
private Integer id;

@Column(name = "display_name", columnDefinition = "TEXT")
private String displayName;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

django와는 무관한 변경사항이 PR에 올라온 것 같습니다

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인해보니 이 스냅샷은 원래 5월에 삭제됐던 파일인데, 그 사이 upstream 머지로 JPA 테스트 픽스처가 test -> users로 바뀌면서 스냅샷이 없는 깨진 상태였습니다.

Django 작업 중 cargo insta accept를 돌리면서 이 누락분도 같이 재생성돼서 커밋에 껴 들어간 것 같습니다.

Django와는 무관하지만 삭제하면 기존 JPA 테스트가 깨지니, 이 파일은 유지하고 별도 커밋(스냅샷 픽스)으로 분리해도 될까요 ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동의합니다

@owjs3901 owjs3901 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.idea ignore이 필요합니다

@2heunxun
2heunxun requested a review from owjs3901 August 8, 2026 14:28
Comment thread CHANGELOG.md Outdated
Comment thread CLAUDE.md
Comment thread crates/vespertide-exporter/src/tests/mod.rs
Comment thread crates/vespertide-exporter/src/tests/mod.rs Outdated
Comment thread crates/vespertide-exporter/src/tests/fixtures/schemas.rs Outdated
@2heunxun
2heunxun requested a review from owjs3901 August 15, 2026 13:27
Comment thread crates/vespertide-config/src/config.rs Outdated
Comment thread crates/vespertide-config/src/config.rs
Comment thread crates/vespertide-config/src/config.rs
Comment thread crates/vespertide-core/src/arbitrary/mod.rs
Comment thread crates/vespertide-core/src/schema/table/tests/mod.rs
/// a matching variant is added here — a compile-time forcing function that replaces the
/// old pattern of a runtime `unreachable!()` guard that only a test could catch.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimpleColumnKind {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동일한 것 같은데 또 선언해야 하는 이유가 있나요

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SimpleColumnType은 #[non_exhaustive]라서 크레이트 밖(exporter 쪽)에서 매치할 때마다 죽은 코드인 와일드카드 arm을 강제로 넣어야 하는데, 그게 커버리지 100% 정책에서 계속 0-hit로 잡힙니다.

SimpleColumnKind는 그 제약이 없는 exhaustive 미러라서 exporter, 쪽(django/types.rs, gorm/mod.rs)에서 와일드카드 없이 완전히 매치할 수 있고, 나중에 타입이 추가되면 From 변환이 컴파일 에러로 알려줘서 놓치는 걸 방지해줍니다!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아마 버전을 고정하거나 로컬로 고정하거나 하면 같은 코드베이스로 인지하고 이를 해결하는 걸로 알고 있는데.. 이거 rust옵션이 있던걸로 기억합니다, 한번 확인바랍니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다시 확인해봤는데, 말씀하신 별도 옵션은 없는 것으로 확인했습니다. RFC 2008과 Rust Reference에서도 #[non_exhaustive]의 적용 여부는 해당 타입을 정의한 crate 내부인지 외부 crate인지에 따라 결정됩니다. 따라서 workspace 멤버십이나 path dependency, 버전 고정 여부로 이 제약을 우회할 수는 없습니다.

즉 vespertide-exporter가 같은 workspace에서 vespertide-core를 로컬 path로 참조하더라도 vespertide-core의 #[non_exhaustive] enum은 여전히 외부 crate의 타입으로 취급되어 wildcard arm이 필요합니다.

따라서 coverage 문제와 향후 variant 추가 누락을 컴파일 타임에 잡는 목적까지 고려하면, 현재의 SimpleColumnKind mirror 타입을 유지하는 방향이 맞을 것 같습니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non_exhaustive를 그러면 제거하는 방향으로 갑시다, 어차피 vespertide를 의존하는 다른 crate가 없는 상황에서 이를 가져가는 것은 고집같네요

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 기존에 갖고 있던 안전성에 대한 고집을 버릴 필요가 있어보입니다 non_exhaustive 제거를 바랍니다

Comment on lines +51 to +54
#[cfg(test)]
pub(crate) fn to_pascal_case_for_tests(s: &str) -> String {
render::to_pascal_case(s)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test 모듈 안에 있어야 합니다 안티패턴입니다

@owjs3901

Copy link
Copy Markdown
Contributor

충돌 해결이 필요합니다.

2heunxun and others added 6 commits August 19, 2026 10:20
Resolves the conflict between this PR's GORM/Django ORM export work
and upstream's independently-added Prisma exporter — both introduced
new backends since the branches diverged. The Orm enum now carries all
seven backends (SeaOrm, SqlAlchemy, SqlModel, Jpa, Gorm, Django,
Prisma); the CLI's export command adopts upstream's export/mod.rs +
export/tests/ restructuring (OrmArg removed, Orm derives
clap::ValueEnum directly) with GORM/Django wiring re-applied on top.

While merging, wiring GORM/Django into the shared cross-ORM orm_cases!
test macro exercised them against scenarios they'd never run before
(non-identifier names, FK relation-name collisions). That surfaced
real bugs: both exporters emitted invalid Go/Python identifiers for
digit-led or hyphenated names, and GORM/Django could emit duplicate
struct/class field names when a relation name collided with an
unrelated column. Fixed via vespertide_naming::sanitize_identifier
(matching the JPA/SeaORM/SQLAlchemy convention) plus collision-aware
relation field naming in both exporters; Django gained explicit
db_column=... support to preserve the real column name whenever the
sanitized attribute name differs from it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts:
#	crates/vespertide-cli/src/commands/export.rs
#	crates/vespertide-config/src/config.rs
#	crates/vespertide-config/src/lib.rs
#	crates/vespertide-exporter/src/tests/fixtures/schemas.rs
@2heunxun
2heunxun requested a review from owjs3901 August 19, 2026 02:12
Comment thread apps/landing/src/app/_components/code-tabs.tsx Outdated
Comment thread apps/landing/src/app/_components/code-tabs.tsx Outdated
Comment thread apps/landing/src/app/_components/code-tabs.tsx Outdated
Comment thread apps/landing/src/app/_components/code-window.tsx Outdated
Comment thread apps/landing/src/app/_components/code-window.tsx Outdated
Comment thread apps/landing/src/app/_components/copy-install.tsx Outdated
Comment thread crates/vespertide-core/src/schema/mod.rs
Comment on lines +61 to +69
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReferenceActionKind {
Cascade,
Restrict,
SetNull,
SetDefault,
NoAction,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것 필요 있는지 확인 필요합니다, 같은 곳에 선언이 되어 있어서

/// a matching variant is added here — a compile-time forcing function that replaces the
/// old pattern of a runtime `unreachable!()` guard that only a test could catch.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimpleColumnKind {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non_exhaustive를 그러면 제거하는 방향으로 갑시다, 어차피 vespertide를 의존하는 다른 crate가 없는 상황에서 이를 가져가는 것은 고집같네요

/// a matching variant is added here — a compile-time forcing function that replaces the
/// old pattern of a runtime `unreachable!()` guard that only a test could catch.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimpleColumnKind {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 기존에 갖고 있던 안전성에 대한 고집을 버릴 필요가 있어보입니다 non_exhaustive 제거를 바랍니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants