enum によるシーリング

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::collections::BTreeMap;
pub enum GetSource {
    WebUrl(String),
    BytesMap(BTreeMap<String, Vec<u8>>),
}

impl GetSource {
    fn get(&self, url: &str) -> Option<&Vec<u8>> {
        match self {
            Self::WebUrl(source) => unimplemented!(),
            Self::BytesMap(map) => map.get(url),
        }
    }
}
  • 動機: API は、それに対して有効な型の特定の一覧を前提として設計されており、 API の利用者がそれを拡張することは想定されていません。

  • Rust の enum は 代数的データ型 であり、各バリアントごとに異なる構造を 定義できます。

    分野によっては、これで問題に対して十分な多態性になる場合があります。 実際に試し、何がうまく機能するか、どの解決策がより理にかなっているかを 確かめてください。

  • API のユーザー向け部分で enum を参照するようにすると、ユーザーはどの型が 有効な入力なのかを把握でき、用意されたメソッドを使ってそれらの型を 構築できます。

    • enum を構成する型に API が内部的に維持する不変条件があり、かつ ユーザーがそれらの型を構築できる唯一の方法が、その不変条件を構築して 維持するコンストラクターを通すことだけであるなら、ジェネリックメソッドへの 入力がその不変条件を満たしていると確信できます。

    • 一方で、enum を構成する型がユーザーが自由に構築できる型である場合は、 サニタイズや解釈を考慮する必要があるかもしれません。