actionbook/rust-skills

m05-type-driven

CRITICAL: Use for type-driven design.

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/actionbook/rust-skills --skill m05-type-driven

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

Type-Driven Design

Layer 1: Language Mechanics

Core Question

How can the type system prevent invalid states?

Before reaching for runtime checks:

  • Can the compiler catch this error?
  • Can invalid states be unrepresentable?
  • Can the type encode the invariant?

Error → Design Question

PatternDon't Just SayAsk Instead
Primitive obsession"It's just a string"What does this value represent?
Boolean flags"Add an is_valid flag"Can states be types?
Optional everywhere"Check for None"Is absence really possible?
Validation at runtime"Return Err if invalid"Can we validate at construction?

Thinking Prompt

Before adding runtime validation:

  1. Can the type encode the constraint?
  • Numeric range → bounded types or newtypes
  • Valid states → type state pattern
  • Semantic meaning → newtype
  1. When is validation possible?
  • At construction → validated newtype
  • At state transition → type state
  • Only at runtime → Result with clear error
  1. Who needs to know the invariant?
  • Compiler → type-level encoding
  • API users → clear type signatures
  • Runtime only → documentation

Trace Up ↑

When type design is unclear:

"Need to validate email format"
    ↑ Ask: Is this a domain value object?
    ↑ Check: m09-domain (Email as Value Object)
    ↑ Check: domain-* (validation requirements)
SituationTrace ToQuestion
What types to createm09-domainWhat's the domain model?
State machine designm09-domainWhat are valid transitions?
Marker trait usagem04-zero-costStatic or dynamic dispatch?

Trace Down ↓

From design to implementation:

"Need type-safe wrapper for primitives"
    ↓ Newtype: struct UserId(u64);

"Need compile-time state validation"
    ↓ Type State: Connection<Connected>

"Need to track phantom type parameters"
    ↓ PhantomData: PhantomData<T>

"Need capability markers"
    ↓ Marker Trait: trait Validated {}

"Need gradual construction"
    ↓ Builder: Builder::new().field(x).build()

Quick Reference

PatternPurposeExample
NewtypeType safetystruct UserId(u64);
Type StateState machineConnection<Connected>
PhantomDataVariance/lifetimePhantomData<&'a T>
Marker TraitCapability flagtrait Validated {}
BuilderGradual constructionBuilder::new().name("x").build()
Sealed TraitPrevent external implmod private { pub trait Sealed {} }

Pattern Examples

Newtype

rust
struct Email(String);  // Not just any string

impl Email {
    pub fn new(s: &str) -> Result<Self, ValidationError> {
        // Validate once, trust forever
        validate_email(s)?;
        Ok(Self(s.to_string()))
    }
}

Type State

rust
struct Connection<State>(TcpStream, PhantomData<State>);

struct Disconnected;
struct Connected;
struct Authenticated;

impl Connection<Disconnected> {
    fn connect(self) -> Connection<Connected> { ... }
}

impl Connection<Connected> {
    fn authenticate(self) -> Connection<Authenticated> { ... }
}

Decision Guide

NeedPattern
Type safety for primitivesNewtype
Compile-time state validationType State
Lifetime/variance markersPhantomData
Capability flagsMarker Trait
Gradual constructionBuilder
Closed set of implsSealed Trait
Zero-sized type markerZST struct

Anti-Patterns

Anti-PatternWhy BadBetter
Boolean flags for statesRuntime errorsType state
String for semantic typesNo type safetyNewtype
Option for uninitializedUnclear invariantBuilder
Public fields with invariantsInvariant violationPrivate + validated new()

Related Skills

WhenSee
Domain modelingm09-domain
Trait designm04-zero-cost
Error handling in constructorsm06-error-handling
Anti-patternsm15-anti-pattern

관련 작업

같은 저장소의 Skills

더 많은 Skills

모든 Skills