How I met my dream language
Hey everyone! 👋
Today, I wanted to share my recent adventure diving into the world of Rust and eframe. Specifically, I had the chance to play around with eframe templates and integrate my own service using Moralis API to fetch wallet tokens. Let me tell you, it was quite the ride! 🚀
First things first, let's talk a bit about Rust. It's a language that's been gaining a lot of traction lately, known for its performance, reliability, and concurrency features. And eframe? Well, it's a neat framework for building GUI applications in Rust, making it a perfect match for what I wanted to accomplish.
Now, onto the fun part – integrating Moralis API into my Rust project. I started by setting up a simple service to fetch wallet tokens using the API. Here's a snippet of the code I wrote:
pub struct ApiService { pub api_key: String, pub endpoint: Endpoint, pub network: Network, } ........
impl ApiService { pub fn new(api_key: String) -> Self { Self { api_key, endpoint: Endpoint::AccountTokens, network: Network::Devnet, } } fn build_url(&self, network: &Network, address: String) -> String { let endpoint = get_endpoint(&self.endpoint); let network = get_network(network); endpoint(network, address) } pub fn get_account_tokens( &self, network: &Network, address: String, ) -> Result<AccountTokensResponse, WalletApiError> { let url = self.build_url(network, address); let req = ureq::get(&url).set("X-API-Key", &self.api_key); let resp: Vec<Token> = req.call()?.into_json()?; Ok(AccountTokensResponse { tokens: resp }) } }
Here is the skeleton of the service :) The rest is available in my github.
Then I have conducted my humble UI using egui:
impl eframe::App for TemplateApp { fn save(&mut self, storage: &mut dyn eframe::Storage) { eframe::set_value(storage, eframe::APP_KEY, self); } fn persist_egui_memory(&self) -> bool { true } fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::menu::bar(ui, |ui| { let is_web = cfg!(target_arch = "wasm32"); if !is_web { ui.menu_button("Settings", |ui| { egui::widgets::global_dark_light_mode_buttons(ui); ui.separator(); ui.horizontal(|ui| { ui.label("API key: "); ui.text_edit_singleline(&mut self.api_key); }); ui.add_space(30.0); let reset_button = ui.button("Reset").on_hover_text("Reset the app state"); if reset_button.clicked() { *self = Default::default(); } }); ui.add_space(16.0); } egui::warn_if_debug_build(ui); }); }); egui::CentralPanel::default().show(ctx, |ui| { ui.horizontal(|ui| { ui.heading("Check your wallet ballance"); ui.menu_button(get_network(&self.network), |ui| { ui.selectable_value(&mut self.network, Network::Mainnet, "Mainnet"); ui.selectable_value(&mut self.network, Network::Devnet, "Devnet"); }); }); ui.add_space(10.0); ui.horizontal(|ui| { ui.label("Wallet address: "); ui.text_edit_singleline(&mut self.wallet_address); let check_button = ui.button("Check"); let clear_button = ui.button("Clear").labelled_by(Id::new("clear_button")); if clear_button.clicked() { self.wallet_address.clear(); } if check_button.clicked() { let tokens = fetch_wallet_balance( &self.network, self.wallet_address.clone(), self.api_key.clone(), ); self.tokens = tokens; } }); ui.add_space(15.0); ui.separator(); egui::ScrollArea::vertical() .id_source("scroll_area") .show(ui, |ui| { for token in self.tokens.iter() { render_token_card(ui, token); } }); }); egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { ui.add_space(5.0); ui.horizontal(|ui| { powered_by_egui_and_eframe(ui); ui.separator(); powered_by_moralis_api(ui); }); ui.add_space(5.0); }); } }
The render_token_card function takes care of displaying token information elegantly, while fetch_wallet_balance orchestrates the interaction with Moralis API to retrieve wallet balances. It's all about making the user experience smooth and intuitive!
And of course, I couldn't resist adding a touch of personality to the UI. At the bottom, you'll find a couple of badges proudly proclaiming that the app is powered by eframe, egui, and Moralis API. Gotta give credit where credit's due, right? 😄
All in all, working with eframe and Rust has been a blast. The combination of Rust's performance and eframe's simplicity made for a delightful development experience. And with Moralis API in the mix, the possibilities are endless! If you're thinking about diving into GUI development with Rust, I highly recommend giving eframe a try – you won't be disappointed.
That's it for today's blog post! Thanks for joining me on this journey, and until next time, happy coding! 🎉