summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-09-06 22:07:28 -0400
committerKjetil Orbekk <kj@orbekk.com>2022-09-06 22:07:28 -0400
commitcab440c8a209ae92eba07d50f7b7127dadbd65c0 (patch)
tree95ad002ad00b6ae99baeb410cc23195286cf5d45
parent77ed77bfa3480a06a3f36b072af5eb8712a1515c (diff)
Move components to a separate module
-rw-r--r--webapp/src/components.rs27
-rw-r--r--webapp/src/components/bidding_box.rs37
-rw-r--r--webapp/src/components/bidding_table.rs48
-rw-r--r--webapp/src/components/card.rs26
-rw-r--r--webapp/src/components/hand.rs38
-rw-r--r--webapp/src/main.rs164
6 files changed, 180 insertions, 160 deletions
diff --git a/webapp/src/components.rs b/webapp/src/components.rs
new file mode 100644
index 0000000..fed31b0
--- /dev/null
+++ b/webapp/src/components.rs
@@ -0,0 +1,27 @@
+use crate::card::Suit;
+
+mod card;
+mod hand;
+mod bidding_table;
+mod bidding_box;
+
+pub use self::card::*;
+pub use self::bidding_box::*;
+pub use self::bidding_table::*;
+pub use self::hand::*;
+
+pub fn suit_css_class(suit: Suit) -> &'static str {
+ match suit {
+ Suit::Club => "suit-club",
+ Suit::Diamond => "suit-diamond",
+ Suit::Heart => "suit-heart",
+ Suit::Spade => "suit-spade",
+ }
+}
+
+pub fn bid_css_class(suit: Option<Suit>) -> &'static str {
+ match suit {
+ None => "suit-notrump",
+ Some(x) => suit_css_class(x),
+ }
+}
diff --git a/webapp/src/components/bidding_box.rs b/webapp/src/components/bidding_box.rs
new file mode 100644
index 0000000..38a543f
--- /dev/null
+++ b/webapp/src/components/bidding_box.rs
@@ -0,0 +1,37 @@
+use yew::prelude::*;
+use crate::bridge_engine::Raise;
+use crate::components::bid_css_class;
+
+#[function_component(BiddingBox)]
+pub fn bidding_box(props: &BiddingBoxProps) -> Html {
+ let bids: Html = Raise::all_raises()
+ .iter()
+ .map(|bid| {
+ let mut class = if Some(*bid) <= props.current_bid {
+ classes!("disabled")
+ } else {
+ classes!("enabled")
+ };
+ class.extend(classes!(bid_css_class(bid.suit)));
+ html! {
+ <div class={class}>
+ { bid.level }
+ </div>
+ }
+ })
+ .collect();
+
+ html! {
+ <div class="bidding-box">
+ { bids }
+ <div>{ "Pass" }</div>
+ <div>{ "X" }</div>
+ <div>{ "XX" }</div>
+ </div>
+ }
+}
+
+#[derive(PartialEq, Properties, Clone)]
+pub struct BiddingBoxProps {
+ pub current_bid: Option<Raise>,
+}
diff --git a/webapp/src/components/bidding_table.rs b/webapp/src/components/bidding_table.rs
new file mode 100644
index 0000000..f4b692a
--- /dev/null
+++ b/webapp/src/components/bidding_table.rs
@@ -0,0 +1,48 @@
+use yew::prelude::*;
+use crate::bridge_engine::{Bid, Bidding, Player};
+use crate::components::bid_css_class;
+
+#[function_component(BiddingTable)]
+pub fn bidding_table(props: &BiddingTableProps) -> Html {
+ let bid = |bid: &Bid| match bid.as_raise() {
+ None => html!{ <div class="bid">{ bid }</div> },
+ Some(raise) => html!{
+ <div class="bid">
+ { raise.level }
+ <div class={ bid_css_class(raise.suit) }/>
+ </div>
+ },
+ };
+ let bids: Html = props
+ .bidding
+ .bids
+ .iter()
+ .map(|b| { bid(b) })
+ .collect();
+ let padding : Html = padding(props.bidding.dealer);
+ html! {
+ <div class="bidding-table">
+ <div class="header">{ "West" }</div>
+ <div class="header">{ "North" }</div>
+ <div class="header">{ "East" }</div>
+ <div class="header">{ "South" }</div>
+ { padding }
+ { bids }
+ </div>
+ }
+}
+
+fn padding(dealer: Player) -> Html {
+ let mut padding : Vec<Html> = vec![];
+ let mut player = Player::West;
+ while player != dealer {
+ padding.push(html! { <div/> });
+ player = player.next();
+ }
+ padding.into_iter().collect()
+}
+
+#[derive(PartialEq, Properties, Clone)]
+pub struct BiddingTableProps {
+ pub bidding: Bidding,
+}
diff --git a/webapp/src/components/card.rs b/webapp/src/components/card.rs
new file mode 100644
index 0000000..6fbe7e7
--- /dev/null
+++ b/webapp/src/components/card.rs
@@ -0,0 +1,26 @@
+use yew::prelude::*;
+use crate::card::{self, Suit, Rank};
+use crate::components::suit_css_class;
+
+#[function_component(Card)]
+pub fn ccard(props: &CardProps) -> Html {
+ html! {
+ <div class="card">
+ <div class={ suit_css_class(props.suit) }>
+ { props.rank }
+ </div>
+ </div>
+ }
+}
+
+#[derive(PartialEq, Properties, Clone)]
+pub struct CardProps {
+ pub suit: Suit,
+ pub rank: Rank,
+}
+
+impl From<card::Card> for CardProps {
+ fn from(card::Card(suit, rank): card::Card) -> Self {
+ CardProps { suit, rank }
+ }
+}
diff --git a/webapp/src/components/hand.rs b/webapp/src/components/hand.rs
new file mode 100644
index 0000000..1a2727c
--- /dev/null
+++ b/webapp/src/components/hand.rs
@@ -0,0 +1,38 @@
+use yew::prelude::*;
+use crate::components::card::{Card, CardProps};
+
+#[function_component(Hand)]
+pub fn hand(props: &HandProps) -> Html {
+ let cards: Html = props
+ .cards
+ .iter()
+ .map(|c| {
+ html! {
+ <Card ..c.clone() />
+ }
+ })
+ .collect();
+
+ html! {
+ <div class="hand">
+ { cards }
+ </div>
+ }
+}
+
+#[derive(Clone, Default, PartialEq, Properties)]
+pub struct HandProps {
+ #[prop_or_default]
+ cards: Vec<CardProps>,
+}
+
+impl<C: Into<CardProps>> FromIterator<C> for HandProps {
+ fn from_iter<Cards>(cards: Cards) -> Self
+ where
+ Cards: std::iter::IntoIterator<Item = C>,
+ {
+ HandProps {
+ cards: cards.into_iter().map(Into::into).collect(),
+ }
+ }
+}
diff --git a/webapp/src/main.rs b/webapp/src/main.rs
index c99eeee..8f94899 100644
--- a/webapp/src/main.rs
+++ b/webapp/src/main.rs
@@ -1,14 +1,12 @@
-use crate::card::{Rank, Suit};
+use crate::card::Suit;
#[allow(unused_imports)]
use log::{debug, error, info, warn};
use yew::prelude::*;
pub mod bridge_engine;
pub mod card;
-use bridge_engine::Bid;
-use bridge_engine::Bidding;
-use bridge_engine::BiddingResult;
-use bridge_engine::Player;
-use bridge_engine::Raise;
+pub mod components;
+use bridge_engine::{Player, BiddingResult};
+use components::{BiddingTable, BiddingBox, Hand, HandProps};
extern crate wee_alloc;
// Use `wee_alloc` as the global allocator.
@@ -73,160 +71,6 @@ pub fn app() -> Html {
}
}
-#[function_component(Hand)]
-pub fn hand(props: &HandProps) -> Html {
- let cards: Html = props
- .cards
- .iter()
- .map(|c| {
- html! {
- <Card ..c.clone() />
- }
- })
- .collect();
-
- html! {
- <div class="hand">
- { cards }
- </div>
- }
-}
-
-pub fn suit_css_class(suit: Suit) -> &'static str {
- match suit {
- Suit::Club => "suit-club",
- Suit::Diamond => "suit-diamond",
- Suit::Heart => "suit-heart",
- Suit::Spade => "suit-spade",
- }
-}
-
-#[derive(Clone, Default, PartialEq, Properties)]
-pub struct HandProps {
- #[prop_or_default]
- cards: Vec<CardProps>,
-}
-
-impl<C: Into<CardProps>> FromIterator<C> for HandProps {
- fn from_iter<Cards>(cards: Cards) -> Self
- where
- Cards: std::iter::IntoIterator<Item = C>,
- {
- HandProps {
- cards: cards.into_iter().map(Into::into).collect(),
- }
- }
-}
-
-#[function_component(Card)]
-pub fn wcard(props: &CardProps) -> Html {
- html! {
- <div class="card">
- <div class={ suit_css_class(props.suit) }>
- { props.rank }
- </div>
- </div>
- }
-}
-
-#[derive(PartialEq, Properties, Clone)]
-pub struct CardProps {
- suit: Suit,
- rank: Rank,
-}
-
-impl From<card::Card> for CardProps {
- fn from(card::Card(suit, rank): card::Card) -> Self {
- CardProps { suit, rank }
- }
-}
-
-pub fn bid_css_class(suit: Option<Suit>) -> &'static str {
- match suit {
- None => "suit-notrump",
- Some(x) => suit_css_class(x),
- }
-}
-
-fn padding(dealer: Player) -> Html {
- let mut padding : Vec<Html> = vec![];
- let mut player = Player::West;
- while player != dealer {
- padding.push(html! { <div/> });
- player = player.next();
- }
- padding.into_iter().collect()
-}
-
-#[function_component(BiddingTable)]
-pub fn bidding_table(props: &BiddingTableProps) -> Html {
- let bid = |bid: &Bid| match bid.as_raise() {
- None => html!{ <div class="bid">{ bid }</div> },
- Some(raise) => html!{
- <div class="bid">
- { raise.level }
- <div class={ bid_css_class(raise.suit) }/>
- </div>
- },
- };
- let bids: Html = props
- .bidding
- .bids
- .iter()
- .map(|b| { bid(b) })
- .collect();
- let padding : Html = padding(props.bidding.dealer);
- html! {
- <div class="bidding-table">
- <div class="header">{ "West" }</div>
- <div class="header">{ "North" }</div>
- <div class="header">{ "East" }</div>
- <div class="header">{ "South" }</div>
- { padding }
- { bids }
- </div>
- }
-}
-
-#[derive(PartialEq, Properties, Clone)]
-pub struct BiddingTableProps {
- bidding: Bidding,
-}
-
-#[function_component(BiddingBox)]
-pub fn bidding_box(props: &BiddingBoxProps) -> Html {
- let bids: Html = Raise::all_raises()
- .iter()
- .map(|bid| {
- let mut class = if Some(*bid) <= props.current_bid {
- classes!("disabled")
- } else {
- classes!("enabled")
- };
- class.extend(classes!(bid_css_class(bid.suit)));
- html! {
- <div class={class}>
- { bid.level }
- </div>
- }
- })
- .collect();
-
- html! {
- <div class="bidding-box">
- { bids }
- <div>{ "Pass" }</div>
- <div>{ "X" }</div>
- <div>{ "XX" }</div>
- </div>
- }
-}
-
-#[derive(PartialEq, Properties, Clone)]
-pub struct BiddingBoxProps {
- current_bid: Option<Raise>,
-}
-
#[cfg(test)]
mod tests {
pub fn test_setup() {