-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve mdo syntax #4
Comments
Because of rust macro system constraint, we can't put In pre rust 1.0, mdo was using |
Ok, thanks for the explanation. Btw, what's the recommended way to do embed non-monadic code in mdo! {} that uses the previous symbols? Currently I'm doing |
Can you point to your usage of mdo, I'd like to read them and maybe propose some syntax to ease the usage of mdo. I think you can't do better than what you're doing now, but we can improve mdo. |
Here is an example that contains the if let Some(data) = mdo! {
places =<< place::Place::all_of_customer(customer_id).ok();
trucks =<< truck::Truck::all_of_customer(customer_id).ok();
truck_types =<< TruckType::all_of_customer(customer_id).ok();
contained_products =<< ContainedProduct::all_of_customer(customer_id).ok();
first_contained_product =<< contained_products.first();
maybe_customer =<< Customer::find(customer_id).ok();
customer =<< maybe_customer;
drivers =<< Driver::all_of_customer(customer_id).ok();
first_place =<< places.first().cloned();
tablets =<< Tablet::all_of_customer(customer_id).ok();
let origin = first_place.location();
let drivers = drivers.into_iter().filter_map(|user| Driver::find(user.id).ok().and_then(|x| x)).collect::<Vec<_>>();
let _ = {
use std::iter::repeat;
for (&driver, maybe_tablet) in drivers.iter().zip(tablets.into_iter().map(Some).chain(repeat(None))) {
let tablet = maybe_tablet.or_else(|| {
use diesel::Connection;
use db;
use models::tablet::*;
let conn = &db::conn();
conn.transaction(move || -> error::Result<_> {
let mut rng = thread_rng();
let unique_id = rng.gen_ascii_chars().take(25).collect::<String>();
let tablet_id = Tablet::create_from(NewTablet {
unique_id: &unique_id,
device_name: "fake demo device"
})?;
let tablet = Tablet::find_conn(conn, tablet_id)?.expect("bug");
tablet.update(&UpdateTablet::customer(Some(customer_id)))?;
Ok(tablet)
}).ok()
}).expect("tablet");
tablet::set_logged_in(driver, Json(tablet.id));
}
};
ret ret(CustomerData {
customer,
contained_product_id: first_contained_product.id,
product_id: first_contained_product.product_id,
truck_data: {
drivers.into_iter().zip(&trucks).filter_map(|(driver, truck)|
mdo! {
_ =<< truck.set_driver(driver.user_id).ok();
ret ret((truck.id, TruckData {
driver,
route: vec![],
truck: Truck::new(0, Vec2::new(0., 0.)),
}))
}
).collect()
},
places: places.into_iter().enumerate().map(|(i, p)| (p.id, to_vrp_place(&origin, p, i))).collect(),
origin,
truck_ids: trucks.into_iter().map(|t| t.id).collect(),
})
} {
customer_data.insert(customer_id, data);
} Also, I often have this pattern: Another pattern I often have is: And maybe |
Whaou! That's a heavy use of mdo 😄 Do you have an idea of a great syntax for the
I think I'd personnally write if let Some(x) = mdo! { ...; ret foo() } {
/* do something with x */
} for I think you're right, |
I forgot, you can write |
Before I was using mdo it was even heavier with lots of map/and_then and deep indentation.. :)
If it's possible with the way macro parsing works, if a statement is not of the form
Yeah, but I meant the extra
Yes, this is what I did in the above example. But what I'd prefer to write is:
I often have db functions returning |
For |
Ah, yes. |
Why not use
<-
(instead of=<<
) just like haskell?(This crate also uses
<-
.)The text was updated successfully, but these errors were encountered: