Skip to content

Commit

Permalink
Implement Resolvable for VAlign and Align
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Aug 4, 2024
1 parent b3ae417 commit df2f91e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 14 deletions.
42 changes: 42 additions & 0 deletions cursive-core/src/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ impl Align {
}
}

impl std::str::FromStr for Align {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"top_left" => Self::top_left(),
"top_center" => Self::top_center(),
"top_right" => Self::top_right(),
"center_left" => Self::center_left(),
"center" => Self::center(),
"center_right" => Self::center_right(),
"bot_left" | "bottom_left" => Self::bot_left(),
"bot_center" | "bottom_center" => Self::bot_center(),
"bot_right" | "bottom_right" => Self::bot_right(),
_ => return Err(()),
})
}
}

/// Horizontal alignment
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HAlign {
Expand All @@ -72,6 +90,18 @@ pub enum HAlign {
Right,
}

impl std::str::FromStr for HAlign {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"left" | "Left" => Self::Left,
"center" | "Center" => Self::Center,
"right" | "Right" => Self::Right,
_ => return Err(()),
})
}
}

/// Vertical alignment
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VAlign {
Expand All @@ -83,6 +113,18 @@ pub enum VAlign {
Bottom,
}

impl std::str::FromStr for VAlign {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"Top" | "top" => Self::Top,
"Center" | "center" => Self::Center,
"Bottom" | "bottom" | "Bot" | "bot" => Self::Bottom,
_ => return Err(()),
})
}
}

impl HAlign {
/// Returns the offset required to position a view.
///
Expand Down
16 changes: 15 additions & 1 deletion cursive-core/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,21 @@ macro_rules! manual_blueprint {

#[cfg(feature = "builder")]
#[macro_export]
/// Define a blueprint to build this view from a config file.
/// Define a blueprint to manually build this view from a config file.
///
/// Note: this is entirely ignored (not even type-checked) if the `builder` feature is not
/// enabled.
///
/// There are 3 variants of this macro:
///
/// * `manual_blueprint!(Identifier, |config, context| make_the_view(...))`
/// This registers the recipe under `Identifier`, and uses the given closure to build
/// the view.
/// * `manual_blueprint!(Identifier from { parse_some_config(...) })`
/// This register under `Identifier` a recipe that forwards the creation to another
/// config using [`Context::build_template`].
/// * `manual_blueprint`(with Identifier, |config, context| Ok(|view| wrap_the_view(view, ...)))`
/// This register a "with" blueprint under `Identifier`, which will prepare a view wrapper.
macro_rules! manual_blueprint {
// Remember to keep the inactive version above in sync
($name:ident from $config_builder:expr) => {
Expand Down
55 changes: 42 additions & 13 deletions cursive-core/src/builder/resolvable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,22 +1009,51 @@ impl Resolvable for crate::view::Margins {
}
}

impl Resolvable for crate::align::Align {
fn from_config(config: &Config, context: &Context) -> Result<Self, Error> {
// Try a string shortcut
if let Some(config_str) = config.as_str() {
if let Ok(align) = config_str.parse() {
return Ok(align);
}

return Err(Error::invalid_config("Unexpected align string", config));
}

let h = context.resolve(&config["h"])?;
let v = context.resolve(&config["v"])?;

Ok(Self { h, v })
}
}

impl Resolvable for crate::align::VAlign {
fn from_config(config: &Config, _context: &Context) -> Result<Self, Error> {
if let Some(config) = config.as_str() {
if let Ok(align) = config.parse() {
return Ok(align);
}
}

Err(Error::invalid_config(
"Expected top, center or bottom",
config,
))
}
}

impl Resolvable for crate::align::HAlign {
fn from_config(config: &Config, _context: &Context) -> Result<Self, Error> {
// TODO: also resolve single-value configs like strings.
// Also when resolving a variable with the wrong type, fallback on loading the type with
// the variable name.
Ok(match config.as_str() {
Some(config) if config == "Left" || config == "left" => Self::Left,
Some(config) if config == "Center" || config == "center" => Self::Center,
Some(config) if config == "Right" || config == "right" => Self::Right,
_ => {
return Err(Error::invalid_config(
"Expected left, center or right",
config,
))
if let Some(config) = config.as_str() {
if let Ok(align) = config.parse() {
return Ok(align);
}
})
}

Err(Error::invalid_config(
"Expected left, center or right",
config,
))
}
}

Expand Down

0 comments on commit df2f91e

Please sign in to comment.