Code structure of a small API client library, idiomatic Rust?

I'm creating a Rust library to interact with the API of the Swedish investment platform Montrose.
They provide a web/JSON API for LLMs, but I figured that I can use it as a regular API (without versioning :sweat_smile:).

I have never written a Rust library before and I'm primarily looking for comments on the structure, naming and API.

The "user" is the programmer using my library in their own crate. The rustdoc in client/tools.rs and types.rs is mainly copied from the MCP's API.

The user can perform simple actions, like listing account holdings, searching for trade instruments and create trade requests. Example use: create-trade.rs

Authentication is performed through OAuth. The end user logs in on a webpage, which creates an access token and a refresh token. The access token is valid for 7 days (currently only 24 h due to a server bug) and the refresh token can refresh it without user interaction for a longer time.

Some things I have thought about:

  • TmrClient<Connected>::connect / connect_with_cb allows the user to use the default BrowserAuthCallbackHandler OAuth callback handler or pass a custom one (like ConsoleAuthHandler). Is this a good choice? Alternatives could be different naming, builder pattern or letting the user pass an instance as an argument?

  • I choose to put the choice of a credential store for the OAuth token as a feature. default selects all keyring-<platform>. If unselected, a JSON file in the end user's config directory is used as storage. I use feature tests in the caller to create the correct storage type: TmrClient::create_cred_store. Is this a good solution for selecting the storage?

  • Are my error types reasonable? result.rs.

  • Is the placement of the code in different files good? It feels a bit suboptimal/rough to me at the moment.

  • Anything else that pops up? What do I don't know that I don't know? :slight_smile:

I have not yet thought about what will happen if the user has a long-running process and both the current access token and refresh token times out, forcing a new user interaction to authenticate. rmcp handles automatically doing a refresh of the access token if I remember correctly.

I tried to generate a graph, but I failed to get something that provides an easy overview. :sweat_smile:
cargo modules dependencies --no-externs --no-sysroot --no-uses | dot -T png > tmp/deps.png

I figured I could put the crate on crates.io and get the rustdoc published, but I currently have git dependency due to some patching in a dependency.