ciniml / rust-dap

CMSIS-DAP Rust implementation
Apache License 2.0
88 stars 10 forks source link

struct の impl を分割するちょうどよい方法はあるでしょうか? #50

Open elfmimi opened 1 year ago

elfmimi commented 1 year ago

この部分を見て下さい。 https://github.com/ciniml/rust-dap/blob/88becf7decd3fcd877c8f8e12bea74f08dadff6d/rust-dap-rp2040/src/pio.rs#L173-L302

この中には impl<C, D> SwdIoSet<C, D> { ... } が4回出てきます。

// Auxiliary low-level function
impl<C, D> SwdIoSet<C, D> { ... }

// Connect and disconnect function
impl<C, D> SwdIoSet<C, D> { ... }

// Basis of SWD interface
impl<C, D> SwdIoSet<C, D> { ... }

// Supplemental functions for SWD
impl<C, D> SwdIoSet<C, D> { ... }

人間的には意味のある分割で、より低レベルの部品を組み立てて必要な機能を構築する形になっています。 一方で、一つの struct の内部なので、部品がどう実装されているかの詳細に強く依存する形で書いています。

ハードウェアの操作を効率的に行いたい部分なので、不必要に抽象化したいわけでもなく、 これはこれで、一応はうまく書けているのではないかと思っています。

そこで質問ですが、 例えば、以下のような trait を持ち込むことを考えてみる、

trait ConnectDisconnectSwdIo {
    fn connect(&mut self);
    fn disconnect(&mut self);
}

trait BasicSwdIo {
    fn write_bits(&mut self, bits: u32, value: u32);
    fn read_bits(&mut self, bits: u32) -> u32;
}

trait SupplementSwdIo {
    fn to_swdio_in(&mut self);
    fn to_swdio_out(&mut self, output: bool);
    fn idle_cycle(&mut self, config: &SwdIoConfig);
}

など、より良い書き方についてアドバイスがあればお聞きしたいです。