Skip to content

Commit

Permalink
Merge pull request #54 from bedrock-crustaceans/form_rework
Browse files Browse the repository at this point in the history
Form rework
  • Loading branch information
theaddonn authored Oct 4, 2024
2 parents b11e92a + b151c61 commit b3baa1d
Show file tree
Hide file tree
Showing 18 changed files with 365 additions and 265 deletions.
5 changes: 3 additions & 2 deletions crates/form/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
serde_json = "1.0"

thiserror = "1.0"

serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
50 changes: 21 additions & 29 deletions crates/form/src/elems/button.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
use serde_json::{json, Value};

use crate::elems::Element;
use crate::error::FormError;

pub enum ButtonImage {
Path(String),
Url(String),
}
use serde::{Deserialize, Deserializer, Serialize};

Check warning on line 1 in crates/form/src/elems/button.rs

View workflow job for this annotation

GitHub Actions / Check

unused import: `Deserializer`

Check warning on line 1 in crates/form/src/elems/button.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `Deserializer`

/// [`Button`] signifies a button incorporated into a [`SimpleForm`](crate::forms::simple::SimpleForm)
/// or [`ModalForm`](crate::forms::modal::ModalForm) form.
/// This button features text and may optionally include an image,
/// which can be sourced from a website or the game's local assets.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Button {
/// Contains the text shown on the button.
/// It can include Minecraft formatting codes and may contain newlines.
pub text: String,
/// Holds an optional image for the button.
pub image: Option<ButtonImage>,
}

impl Element for Button {
fn elem_serialize(&self) -> Value {
let (button_type, image_data) = match &self.image {
None => ("path", ""),
Some(v) => match v {
ButtonImage::Path(v) => ("path", v.as_str()),
ButtonImage::Url(v) => ("url", v.as_str()),
},
};

json!({
"type": button_type,
"text": self.text,
"data": image_data,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
/// An image for a [`Button`].
/// Can either be an url or a path to a resource location.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "data")]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub enum ButtonImage {
/// Refers to an image stored at the given resource location in the local game/texture packs.
Path(String),
/// Refers to an image stored at the given url.
Url(String),
}
33 changes: 12 additions & 21 deletions crates/form/src/elems/dropdown.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
use serde_json::{json, Value};
use serde::{Deserialize, Serialize};

use crate::elems::Element;
use crate::error::FormError;

pub struct DropDown {
/// [`Dropdown`] represents a dropdown which, when clicked,
/// opens a window with the options set in the Options field.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Dropdown {
/// Refers to the content shown above the dropdown element.
/// It may include Minecraft formatting codes.
pub text: String,
/// Contains a list of choices that a player can select from.
pub options: Vec<String>,
pub default_index: i32,
}

impl Element for DropDown {
fn elem_serialize(&self) -> Value {
json!({
"type": "dropdown",
"text": self.text,
"default": self.default_index,
"options": self.options,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
/// Refers to the index in the Options slice designated as the default.
/// The value at this index within the Options slice will be chosen.
pub default: i32,
}
31 changes: 12 additions & 19 deletions crates/form/src/elems/input.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
use serde_json::{json, Value};

use crate::elems::Element;
use crate::error::FormError;
use serde::{Deserialize, Serialize};

/// [`Input`] represents a text input field element
/// where players can enter text of any length without restrictions.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Input {
/// Refers to the content displayed over the input element,
/// which may include Minecraft formatting codes.
pub text: String,
/// Represents the pre-filled value in the input field.
/// The player can remove this value and enter their own text,
/// which may include Minecraft formatting codes.
pub default: String,
/// Is shown in the input box when no player-entered text is present.
/// This text can include Minecraft formatting codes.
pub placeholder: String,
}

impl Element for Input {
fn elem_serialize(&self) -> Value {
json!({
"type": "input",
"text": self.text,
"default": self.default,
"placeholder": self.placeholder,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
}
23 changes: 6 additions & 17 deletions crates/form/src/elems/label.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
use serde_json::{json, Value};

use crate::elems::Element;
use crate::error::FormError;
use serde::{Deserialize, Serialize};

/// [`Label`] represents a static text box on a form.
/// It is used purely for displaying text and does not accept any player input.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Label {
/// Represents the [`Label's`](Label) content, which may include Minecraft formatting codes.
pub text: String,
}

impl Element for Label {
fn elem_serialize(&self) -> Value {
json!({
"type": "label",
"text": self.text,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
}
26 changes: 19 additions & 7 deletions crates/form/src/elems/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::error::FormError;
use serde_json::Value;
use crate::elems::dropdown::Dropdown;
use crate::elems::input::Input;
use crate::elems::label::Label;
use crate::elems::slider::Slider;
use crate::elems::step_slider::StepSlider;
use crate::elems::toggle::Toggle;
use serde::{Deserialize, Serialize};

pub mod button;
pub mod dropdown;
Expand All @@ -9,9 +14,16 @@ pub mod slider;
pub mod step_slider;
pub mod toggle;

pub trait Element {
fn elem_serialize(&self) -> Value;
fn elem_deserialize(elem_json: Value) -> Result<Self, FormError>
where
Self: Sized;
/// An enum of all possible [`Elements`](Element) for a [`CustomForm`](crate::forms::custom::CustomForm).
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub enum Element {
Dropdown(Dropdown),
Input(Input),
Label(Label),
Slider(Slider),
StepSlider(StepSlider),
Toggle(Toggle),
}
34 changes: 13 additions & 21 deletions crates/form/src/elems/slider.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
use serde_json::{json, Value};

use crate::elems::Element;
use crate::error::FormError;
use serde::{Deserialize, Serialize};

/// [`Slider`] represents a slider element,
/// allowing players to move it within its defined range to select a value.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Slider {
/// Represents the text displayed over the slider element.
/// It may include Minecraft formatting codes.
pub text: String,
/// Specifies the lowest value that can be selected on the slider.
pub min: f64,
/// Specifies the highest value that can be selected on the slider
pub max: f64,
/// Determines the amount of space each slider step occupies.
/// For instance, setting it to 1.0 allows the player to select only whole values.
#[serde(rename = "step")]
pub step_size: f64,
/// Default value filled out for the slider.
pub default: f64,
}

impl Element for Slider {
fn elem_serialize(&self) -> Value {
json!({
"type": "slider",
"text": self.text,
"min": self.min,
"max": self.max,
"step": self.step_size,
"default": self.default,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
}
34 changes: 13 additions & 21 deletions crates/form/src/elems/step_slider.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
use serde_json::{json, Value};
use serde::{Deserialize, Serialize};

use crate::elems::Element;
use crate::error::FormError;

/// A combination of DropDown and Slider
/// [`StepSlider`] is an element that functions as a slider with multiple selectable options.
/// It effectively merges the characteristics of a dropdown and a slider,
/// appearing like a slider while incorporating features typical of a dropdown.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct StepSlider {
/// Represents the text displayed over the step slider element.
/// It may include Minecraft formatting codes.
pub text: String,
/// Contains a list of choices that a player can select from.
#[serde(rename = "steps")]
pub options: Vec<String>,
pub default_index: i32,
}

impl Element for StepSlider {
fn elem_serialize(&self) -> Value {
json!({
"type": "step_slider",
"text": self.text,
"default": self.default_index,
"steps": self.options,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
/// Refers to the index in the Options slice designated as the default.
/// The value at this index within the Options slice will be chosen.
pub default: i32,
}
25 changes: 7 additions & 18 deletions crates/form/src/elems/toggle.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
use serde_json::{json, Value};

use crate::elems::Element;
use crate::error::FormError;
use serde::{Deserialize, Serialize};

/// [`Toggle`] represents a switch-like element.
/// Players can turn it either on or off, resulting in a value of `true` when on and `false` when off.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Toggle {
/// The text displayed over the toggle element, which may include Minecraft formatting codes.
pub text: String,
/// Specifies whether the toggle should be on or off by default.
pub default: bool,
}

impl Element for Toggle {
fn elem_serialize(&self) -> Value {
json!({
"type": "toggle",
"text": self.text,
"default": self.default,
})
}

fn elem_deserialize(elem_json: Value) -> Result<Self, FormError> {
todo!()
}
}
15 changes: 15 additions & 0 deletions crates/form/src/forms/custom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::elems::Element;
use serde::{Deserialize, Serialize};

/// [`CustomForm`] represents a form that can be sent to a player,
/// containing fields that the player may fill out.
/// All possible fields are in the [`Element`] enum.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CustomForm {
/// Refers to the title.
pub title: String,
/// All elements in the [`CustomForm`](CustomForm). Sequence is maintained.
#[serde(rename = "content")]
pub elements: Vec<Element>,
}
Loading

0 comments on commit b3baa1d

Please sign in to comment.