lib.rs

31.8 kB · rust · 879 lines

1#![allow(non_camel_case_types, non_snake_case, clippy::too_many_arguments)]23mod hand;45use wasm_bindgen::prelude::*;67/// Draws one seeded artwork and returns its PNG bytes: a random flat tile under the default recipe8#[wasm_bindgen]9pub fn background(seed: JsValue, width: usize, height: usize) -> Result<Vec<u8>, JsValue> {10    let seed = hand::u64_from_js(&seed)?;11    let value = mrlyrs::gen::background(seed, width, height).map_err(hand::throw)?;12    Ok(value)13}1415/// Builds the flat cell the tile describes.16#[wasm_bindgen]17pub fn build_build_2d(tile: &Tile) -> Result<JsValue, JsValue> {18    let value = mrlyrs::gen::build::build_2d(&tile.inner).map_err(hand::throw)?;19    hand::cell2d_to_js(&value)20}2122/// Builds the cube the tile describes.23#[wasm_bindgen]24pub fn build_build_3d(tile: &Tile) -> Result<JsValue, JsValue> {25    let value = mrlyrs::gen::build::build_3d(&tile.inner).map_err(hand::throw)?;26    hand::cell3d_to_js(&value)27}2829/// Builds the tile's cube and flattens it through its projection.30#[wasm_bindgen]31pub fn build_build_6d(hex: JsValue) -> Result<JsValue, JsValue> {32    let hex = hand::from_js::<mrlyrs::gen::build::HexTile>(&hex)?;33    let value = mrlyrs::gen::build::build_6d(&hex).map_err(hand::throw)?;34    hand::cell6d_to_js(&value)35}3637/// Draws a random flat tile from the stream, rotations from the four quarter-turns.38#[wasm_bindgen]39pub fn build_create_2d(config: JsValue, rng: &mut hand::Rng) -> Result<Tile, JsValue> {40    let config = hand::from_js::<mrlyrs::gen::draw::ConfigNd<2>>(&config)?;41    let value = mrlyrs::gen::build::create_2d(&config, rng.stream()).map_err(hand::throw)?;42    Ok(Tile { inner: value })43}4445/// Draws a cube tile from the config with cube orientations drawn from the stream.46#[wasm_bindgen]47pub fn build_create_3d(config: JsValue, rng: &mut hand::Rng) -> Result<Tile, JsValue> {48    let config = hand::from_js::<mrlyrs::gen::draw::ConfigNd<3>>(&config)?;49    let value = mrlyrs::gen::build::create_3d(&config, rng.stream()).map_err(hand::throw)?;50    Ok(Tile { inner: value })51}5253/// Draws a cube tile from the config under a projection drawn from the stream.54#[wasm_bindgen]55pub fn build_create_6d(config: JsValue, rng: &mut hand::Rng) -> Result<JsValue, JsValue> {56    let config = hand::from_js::<mrlyrs::gen::draw::ConfigNd<3>>(&config)?;57    let value = mrlyrs::gen::build::create_6d(&config, rng.stream()).map_err(hand::throw)?;58    hand::to_js(&value)59}6061/// Draws a random flat tile up to the given size under the default config.62#[wasm_bindgen]63pub fn build_random_tile_2d(max_size: usize, rng: &mut hand::Rng) -> Result<Tile, JsValue> {64    let value = mrlyrs::gen::build::random_tile_2d(max_size, rng.stream()).map_err(hand::throw)?;65    Ok(Tile { inner: value })66}6768/// Draws a random cube tile up to the given size.69#[wasm_bindgen]70pub fn build_random_tile_3d(max_size: usize, rng: &mut hand::Rng) -> Result<Tile, JsValue> {71    let value = mrlyrs::gen::build::random_tile_3d(max_size, rng.stream()).map_err(hand::throw)?;72    Ok(Tile { inner: value })73}7475/// Draws a random cube tile up to the given size under a random projection.76#[wasm_bindgen]77pub fn build_random_tile_6d(max_size: usize, rng: &mut hand::Rng) -> Result<JsValue, JsValue> {78    let value = mrlyrs::gen::build::random_tile_6d(max_size, rng.stream()).map_err(hand::throw)?;79    hand::to_js(&value)80}8182/// Returns the plane's bang code of a classic design, or None for one outside the plane.83#[wasm_bindgen]84pub fn classic_code(design: JsValue) -> Result<JsValue, JsValue> {85    let design = hand::from_js::<mrlyrs::gen::recipe::Design>(&design)?;86    let value = mrlyrs::gen::classic_code(design);87    hand::option_to_js(value.as_ref(), |x1| Ok(JsValue::from_str(&x1.to_string())))88}8990/// Returns the bang code of a named design in a dimension, or None where it has no design.91#[wasm_bindgen]92pub fn classic_code_nd(design: JsValue, dimension: usize) -> Result<JsValue, JsValue> {93    let design = hand::from_js::<mrlyrs::gen::recipe::Design>(&design)?;94    let value = mrlyrs::gen::classic_code_nd(design, dimension);95    hand::option_to_js(value.as_ref(), |x1| Ok(JsValue::from_str(&x1.to_string())))96}9798/// Draws a hex key of the given length from the stream.99#[wasm_bindgen]100pub fn hex_key(length: usize, rng: &mut hand::Rng) -> Result<String, JsValue> {101    let value = mrlyrs::gen::hex_key(length, rng.stream());102    Ok(value)103}104105/// Draws one of the four flat classics from the stream: carpet, net, vertical tree or void.106#[wasm_bindgen]107pub fn random_design(rng: &mut hand::Rng) -> Result<JsValue, JsValue> {108    let value = mrlyrs::gen::random_design(rng.stream());109    hand::to_js(&value)110}111112/// Draws a design's turn from the stream: a tree turns 0 or 1, every other design 0 to 3.113#[wasm_bindgen]114pub fn random_rotation(design: JsValue, rng: &mut hand::Rng) -> Result<u8, JsValue> {115    let design = hand::from_js::<mrlyrs::gen::recipe::Design>(&design)?;116    let value = mrlyrs::gen::random_rotation(design, rng.stream());117    Ok(value)118}119120/// Returns the classic designs for a dimension.121#[wasm_bindgen]122pub fn recipe_classics(dimension: usize) -> Result<JsValue, JsValue> {123    let value = mrlyrs::gen::recipe::classics(dimension);124    hand::to_js(&value)125}126127/// Returns every flat size in the range that passes the parity filter.128#[wasm_bindgen]129pub fn recipe_generals(min_size: usize, max_size: usize, parity: JsValue) -> Result<Vec<usize>, JsValue> {130    let parity = hand::from_js::<mrlyrs::gen::Parity>(&parity)?;131    let value = mrlyrs::gen::recipe::generals(min_size, max_size, parity);132    Ok(value)133}134135/// Returns every factor list of depth two and beyond whose product lands in the size range.136#[wasm_bindgen]137pub fn recipe_nestings(min_size: usize, max_size: usize, parity: JsValue) -> Result<JsValue, JsValue> {138    let parity = hand::from_js::<mrlyrs::gen::Parity>(&parity)?;139    let value = mrlyrs::gen::recipe::nestings(min_size, max_size, parity);140    hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))141}142143/// Returns every factor and level whose power lands in the size range.144#[wasm_bindgen]145pub fn recipe_powers(min_size: usize, max_size: usize, parity: JsValue) -> Result<JsValue, JsValue> {146    let parity = hand::from_js::<mrlyrs::gen::Parity>(&parity)?;147    let value = mrlyrs::gen::recipe::powers(min_size, max_size, parity);148    hand::to_js(&value)149}150151/// Returns every count-long factor list whose product lands in the size range.152#[wasm_bindgen]153pub fn recipe_products(min_size: usize, max_size: usize, count: usize, parity: JsValue) -> Result<JsValue, JsValue> {154    let parity = hand::from_js::<mrlyrs::gen::Parity>(&parity)?;155    let value = mrlyrs::gen::recipe::products(min_size, max_size, count, parity);156    hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))157}158159/// Returns the side a factor raised to a level makes, or None when no usize holds it.160#[wasm_bindgen]161pub fn recipe_size(number: JsValue, level: JsValue) -> Result<JsValue, JsValue> {162    let number = hand::i64_from_js(&number)?;163    let level = hand::i64_from_js(&level)?;164    let value = mrlyrs::gen::recipe::size(number, level);165    hand::to_js(&value)166}167168/// Builds the mask of a mosaic tile: the two trees of the side, two where they cross.169#[wasm_bindgen]170pub fn tree_mask(n: usize) -> Result<JsValue, JsValue> {171    let value = mrlyrs::gen::tree_mask(n).map_err(hand::throw)?;172    hand::tensor_to_js(&value)173}174175/// Draws a variation's seed from the stream, then the variation itself on that seed, with a176#[wasm_bindgen]177pub fn variation_create(config: JsValue, rng: &mut hand::Rng) -> Result<variation_Variation, JsValue> {178    let config = hand::from_js::<mrlyrs::gen::variation::Config>(&config)?;179    let value = mrlyrs::gen::variation::create(&config, rng.stream()).map_err(hand::throw)?;180    Ok(variation_Variation { inner: value })181}182183/// Builds the variation's base cell and draws its paint from the stream, painting the base184#[wasm_bindgen]185pub fn variation_generate(variation: &variation_Variation, config: JsValue, rng: &mut hand::Rng) -> Result<variation_Variation, JsValue> {186    let config = hand::from_js::<mrlyrs::gen::variation::Config>(&config)?;187    let value = mrlyrs::gen::variation::generate(variation.inner.clone(), &config, rng.stream()).map_err(hand::throw)?;188    Ok(variation_Variation { inner: value })189}190191/// Renders every file of the variation to PNG at the given scale, scattering a Random edition192#[wasm_bindgen]193pub fn variation_render(variation: &variation_Variation, scale: usize, rng: &mut hand::Rng) -> Result<variation_Variation, JsValue> {194    let value = mrlyrs::gen::variation::render(variation.inner.clone(), scale, rng.stream()).map_err(hand::throw)?;195    Ok(variation_Variation { inner: value })196}197198/// The five classic designs of the plane.199#[wasm_bindgen]200pub fn recipe_CLASSICS_2D() -> Result<JsValue, JsValue> {201    let value = mrlyrs::gen::recipe::CLASSICS_2D;202    hand::to_js(&value)203}204205/// The six classic designs of the cube.206#[wasm_bindgen]207pub fn recipe_CLASSICS_3D() -> Result<JsValue, JsValue> {208    let value = mrlyrs::gen::recipe::CLASSICS_3D;209    hand::to_js(&value)210}211212/// The deepest fractal level a tile may take.213#[wasm_bindgen]214pub fn recipe_MAX_LEVEL() -> Result<usize, JsValue> {215    let value = mrlyrs::gen::recipe::MAX_LEVEL;216    Ok(value)217}218219/// The largest side, number or factor a tile may take.220#[wasm_bindgen]221pub fn recipe_MAX_SIDE() -> Result<usize, JsValue> {222    let value = mrlyrs::gen::recipe::MAX_SIDE;223    Ok(value)224}225226/// The most slots a magic tile may take.227#[wasm_bindgen]228pub fn recipe_MAX_SLOTS() -> Result<usize, JsValue> {229    let value = mrlyrs::gen::recipe::MAX_SLOTS;230    Ok(value)231}232233/// The smallest side, number or factor a tile may take.234#[wasm_bindgen]235pub fn recipe_MIN_SIDE() -> Result<usize, JsValue> {236    let value = mrlyrs::gen::recipe::MIN_SIDE;237    Ok(value)238}239240/// A complete recipe for one tile.241#[wasm_bindgen]242pub struct Tile {243    inner: mrlyrs::gen::Tile,244}245246#[wasm_bindgen]247impl Tile {248    /// Reads the Tile from its plain data.249    #[wasm_bindgen(js_name = "from")]250    pub fn from_plain(data: JsValue) -> Result<Tile, JsValue> {251        Ok(Tile { inner: hand::from_js(&data)? })252    }253    /// Writes the Tile as plain data.254    #[wasm_bindgen(js_name = "toJSON")]255    pub fn to_plain(&self) -> Result<JsValue, JsValue> {256        hand::to_js(&self.inner)257    }258    /// The construction family.259    #[wasm_bindgen(getter)]260    pub fn group(&self) -> Result<JsValue, JsValue> {261        let value = self.inner.group;262        hand::to_js(&value)263    }264    #[wasm_bindgen(setter)]265    pub fn set_group(&mut self, value: JsValue) -> Result<(), JsValue> {266        let value = hand::from_js::<mrlyrs::gen::Group>(&value)?;267        self.inner.group = value;268        Ok(())269    }270    /// The base factor of the construction.271    #[wasm_bindgen(getter)]272    pub fn factor(&self) -> Result<usize, JsValue> {273        let value = self.inner.factor;274        Ok(value)275    }276    #[wasm_bindgen(setter)]277    pub fn set_factor(&mut self, value: usize) -> Result<(), JsValue> {278        self.inner.factor = value;279        Ok(())280    }281    /// The origin of each layer.282    #[wasm_bindgen(getter)]283    pub fn sources(&self) -> Result<JsValue, JsValue> {284        let value = self.inner.sources.clone();285        hand::to_js(&value)286    }287    #[wasm_bindgen(setter)]288    pub fn set_sources(&mut self, value: JsValue) -> Result<(), JsValue> {289        let value = hand::from_js::<Vec<mrlyrs::gen::recipe::Source>>(&value)?;290        self.inner.sources = value;291        Ok(())292    }293    /// The grid size of each source.294    #[wasm_bindgen(getter)]295    pub fn numbers(&self) -> Result<Vec<usize>, JsValue> {296        let value = self.inner.numbers.clone();297        Ok(value)298    }299    #[wasm_bindgen(setter)]300    pub fn set_numbers(&mut self, value: Vec<usize>) -> Result<(), JsValue> {301        self.inner.numbers = value;302        Ok(())303    }304    /// The fractal level of each source.305    #[wasm_bindgen(getter)]306    pub fn levels(&self) -> Result<Vec<usize>, JsValue> {307        let value = self.inner.levels.clone();308        Ok(value)309    }310    #[wasm_bindgen(setter)]311    pub fn set_levels(&mut self, value: Vec<usize>) -> Result<(), JsValue> {312        self.inner.levels = value;313        Ok(())314    }315    /// The quarter-turn rotation of each source.316    #[wasm_bindgen(getter)]317    pub fn rotations(&self) -> Result<Vec<usize>, JsValue> {318        let value = self.inner.rotations.clone();319        Ok(value)320    }321    #[wasm_bindgen(setter)]322    pub fn set_rotations(&mut self, value: Vec<usize>) -> Result<(), JsValue> {323        self.inner.rotations = value;324        Ok(())325    }326    /// Whether the finished tile inverts.327    #[wasm_bindgen(getter)]328    pub fn invert(&self) -> Result<bool, JsValue> {329        let value = self.inner.invert;330        Ok(value)331    }332    #[wasm_bindgen(setter)]333    pub fn set_invert(&mut self, value: bool) -> Result<(), JsValue> {334        self.inner.invert = value;335        Ok(())336    }337    /// Whether the finished tile flips.338    #[wasm_bindgen(getter)]339    pub fn flip(&self) -> Result<bool, JsValue> {340        let value = self.inner.flip;341        Ok(value)342    }343    #[wasm_bindgen(setter)]344    pub fn set_flip(&mut self, value: bool) -> Result<(), JsValue> {345        self.inner.flip = value;346        Ok(())347    }348    /// The tile's width in cells.349    #[wasm_bindgen(getter)]350    pub fn width(&self) -> Result<usize, JsValue> {351        let value = self.inner.width;352        Ok(value)353    }354    #[wasm_bindgen(setter)]355    pub fn set_width(&mut self, value: usize) -> Result<(), JsValue> {356        self.inner.width = value;357        Ok(())358    }359    /// The tile's height in cells.360    #[wasm_bindgen(getter)]361    pub fn height(&self) -> Result<usize, JsValue> {362        let value = self.inner.height;363        Ok(value)364    }365    #[wasm_bindgen(setter)]366    pub fn set_height(&mut self, value: usize) -> Result<(), JsValue> {367        self.inner.height = value;368        Ok(())369    }370    /// Checks that the slots, numbers and sizes agree.371    pub fn check(&self) -> Result<(), JsValue> {372        self.inner.check().map_err(hand::throw)?;373        Ok(())374    }375    /// Returns whether the recipe is a magic tile of one repeated source at one repeated number,376    pub fn degenerate(&self) -> Result<bool, JsValue> {377        let value = self.inner.degenerate();378        Ok(value)379    }380    /// Returns the larger of width and height.381    pub fn max_size(&self) -> Result<usize, JsValue> {382        let value = self.inner.max_size();383        Ok(value)384    }385    /// Builds an empty tile in a group.386    #[wasm_bindgen(constructor)]387    pub fn new(group: JsValue) -> Result<Tile, JsValue> {388        let group = hand::from_js::<mrlyrs::gen::Group>(&group)?;389        let value = mrlyrs::gen::Tile::new(group);390        Ok(Tile { inner: value })391    }392    /// Recomputes the factor and side length the group and numbers imply, zero when they overflow.393    pub fn resize(&mut self) -> Result<(), JsValue> {394        self.inner.resize();395        Ok(())396    }397    /// Sets the tile's width and height.398    pub fn size(&self, width: usize, height: usize) -> Result<Tile, JsValue> {399        let value = self.inner.clone().size(width, height);400        Ok(Tile { inner: value })401    }402}403404/// A tile recipe folded to its one canonical object.405#[wasm_bindgen]406pub struct name_Tile {407    inner: mrlyrs::gen::name::Tile,408}409410#[wasm_bindgen]411impl name_Tile {412    /// Reads the Tile from its plain data.413    #[wasm_bindgen(js_name = "from")]414    pub fn from_plain(data: JsValue) -> Result<name_Tile, JsValue> {415        Ok(name_Tile { inner: hand::from_js(&data)? })416    }417    /// Writes the Tile as plain data.418    #[wasm_bindgen(js_name = "toJSON")]419    pub fn to_plain(&self) -> Result<JsValue, JsValue> {420        hand::to_js(&self.inner)421    }422    /// The one design of a flat or fractal tile.423    #[wasm_bindgen(getter)]424    pub fn code(&self) -> Result<JsValue, JsValue> {425        let value = self.inner.code;426        hand::option_to_js(value.as_ref(), |x1| Ok(JsValue::from_str(&x1.to_string())))427    }428    #[wasm_bindgen(setter)]429    pub fn set_code(&mut self, value: JsValue) -> Result<(), JsValue> {430        let value = hand::option_from_js(&value, hand::u128_from_js)?;431        self.inner.code = value;432        Ok(())433    }434    /// The mask code of a special tile.435    #[wasm_bindgen(getter)]436    pub fn special(&self) -> Result<JsValue, JsValue> {437        let value = self.inner.special;438        hand::option_to_js(value.as_ref(), |x1| Ok(JsValue::from_str(&x1.to_string())))439    }440    #[wasm_bindgen(setter)]441    pub fn set_special(&mut self, value: JsValue) -> Result<(), JsValue> {442        let value = hand::option_from_js(&value, hand::u128_from_js)?;443        self.inner.special = value;444        Ok(())445    }446    /// The letters of a magic tile, first letter outermost.447    #[wasm_bindgen(getter)]448    pub fn magic(&self) -> Result<JsValue, JsValue> {449        let value = self.inner.magic.clone();450        hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))451    }452    #[wasm_bindgen(setter)]453    pub fn set_magic(&mut self, value: JsValue) -> Result<(), JsValue> {454        let value = hand::list_from_js(&value, hand::u128_from_js)?;455        self.inner.magic = value;456        Ok(())457    }458    /// The three codes of a mosaic tile.459    #[wasm_bindgen(getter)]460    pub fn mosaic(&self) -> Result<JsValue, JsValue> {461        let value = self.inner.mosaic.clone();462        hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))463    }464    #[wasm_bindgen(setter)]465    pub fn set_mosaic(&mut self, value: JsValue) -> Result<(), JsValue> {466        let value = hand::list_from_js(&value, hand::u128_from_js)?;467        self.inner.mosaic = value;468        Ok(())469    }470    /// The side of the mask of a special or mosaic tile.471    #[wasm_bindgen(getter)]472    pub fn factor(&self) -> Result<JsValue, JsValue> {473        let value = self.inner.factor;474        hand::to_js(&value)475    }476    #[wasm_bindgen(setter)]477    pub fn set_factor(&mut self, value: JsValue) -> Result<(), JsValue> {478        let value = hand::from_js::<Option<usize>>(&value)?;479        self.inner.factor = value;480        Ok(())481    }482    /// The side each slot renders at, one per letter for a magic tile.483    #[wasm_bindgen(getter)]484    pub fn side(&self) -> Result<JsValue, JsValue> {485        let value = self.inner.side.clone();486        hand::to_js(&value)487    }488    #[wasm_bindgen(setter)]489    pub fn set_side(&mut self, value: JsValue) -> Result<(), JsValue> {490        let value = hand::from_js::<mrlyrs::gen::name::Slots>(&value)?;491        self.inner.side = value;492        Ok(())493    }494    /// The power a fractal tile is raised to, absent at one.495    #[wasm_bindgen(getter)]496    pub fn level(&self) -> Result<JsValue, JsValue> {497        let value = self.inner.level;498        hand::to_js(&value)499    }500    #[wasm_bindgen(setter)]501    pub fn set_level(&mut self, value: JsValue) -> Result<(), JsValue> {502        let value = hand::from_js::<Option<usize>>(&value)?;503        self.inner.level = value;504        Ok(())505    }506    /// The quarter turns of each slot, absent when nothing turns.507    #[wasm_bindgen(getter)]508    pub fn turn(&self) -> Result<JsValue, JsValue> {509        let value = self.inner.turn.clone();510        hand::to_js(&value)511    }512    #[wasm_bindgen(setter)]513    pub fn set_turn(&mut self, value: JsValue) -> Result<(), JsValue> {514        let value = hand::from_js::<mrlyrs::gen::name::Slots>(&value)?;515        self.inner.turn = value;516        Ok(())517    }518    /// Whether a special tile flips its mask.519    #[wasm_bindgen(getter)]520    pub fn flip(&self) -> Result<bool, JsValue> {521        let value = self.inner.flip;522        Ok(value)523    }524    #[wasm_bindgen(setter)]525    pub fn set_flip(&mut self, value: bool) -> Result<(), JsValue> {526        self.inner.flip = value;527        Ok(())528    }529    /// Whether the finished tile inverts.530    #[wasm_bindgen(getter)]531    pub fn invert(&self) -> Result<bool, JsValue> {532        let value = self.inner.invert;533        Ok(value)534    }535    #[wasm_bindgen(setter)]536    pub fn set_invert(&mut self, value: bool) -> Result<(), JsValue> {537        self.inner.invert = value;538        Ok(())539    }540    /// Folds a decoded value to its canonical form, or an error for one outside the kind.541    pub fn checked(&self) -> Result<name_Tile, JsValue> {542        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::checked(self.inner.clone()).map_err(hand::throw)?;543        Ok(name_Tile { inner: value })544    }545    /// Reads a filename back into the value, or an error.546    pub fn from_file(text: &str) -> Result<name_Tile, JsValue> {547        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::from_file(text).map_err(hand::throw)?;548        Ok(name_Tile { inner: value })549    }550    /// Reads a JSON object into its canonical value, or an error naming the broken key.551    pub fn from_json(text: &str) -> Result<name_Tile, JsValue> {552        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::from_json(text).map_err(hand::throw)?;553        Ok(name_Tile { inner: value })554    }555    /// Reads a path and query string back into the value, or an error.556    pub fn from_url(text: &str) -> Result<name_Tile, JsValue> {557        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::from_url(text).map_err(hand::throw)?;558        Ok(name_Tile { inner: value })559    }560    /// Folds a recipe to its name.561    pub fn of(recipe: &Tile) -> Result<name_Tile, JsValue> {562        let value = mrlyrs::gen::name::Tile::of(&recipe.inner).map_err(hand::throw)?;563        Ok(name_Tile { inner: value })564    }565    /// Builds the recipe the name folds, resized and checked.566    pub fn recipe(&self) -> Result<Tile, JsValue> {567        let value = self.inner.recipe().map_err(hand::throw)?;568        Ok(Tile { inner: value })569    }570    /// Prints the kind and the `key=value` pairs joined by underscores, lists in brackets, or an error when the name does not read back.571    pub fn to_file(&self) -> Result<String, JsValue> {572        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::to_file(&self.inner).map_err(hand::throw)?;573        Ok(value)574    }575    /// Prints the first eight hex digits of the sha256 of the canonical JSON.576    pub fn to_id(&self) -> Result<String, JsValue> {577        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::to_id(&self.inner);578        Ok(value)579    }580    /// Prints the canonical JSON object.581    pub fn to_json(&self) -> Result<String, JsValue> {582        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::to_json(&self.inner);583        Ok(value)584    }585    /// Prints the kind and the keys as a line of prose for pages, or an error when the name does not read back.586    pub fn to_mrly(&self) -> Result<String, JsValue> {587        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::to_mrly(&self.inner).map_err(hand::throw)?;588        Ok(value)589    }590    /// Prints the kind as a path and the keys as a query string, lists comma-joined, or an error when the name does not read back.591    pub fn to_url(&self) -> Result<String, JsValue> {592        let value = <mrlyrs::gen::name::Tile as mrlyrs::math::name::Named>::to_url(&self.inner).map_err(hand::throw)?;593        Ok(value)594    }595}596597/// One rendering of an artwork, sized in tile repetitions.598#[wasm_bindgen]599pub struct variation_File {600    inner: mrlyrs::gen::variation::File,601}602603#[wasm_bindgen]604impl variation_File {605    /// Reads the File from its plain data.606    #[wasm_bindgen(js_name = "from")]607    pub fn from_plain(data: JsValue) -> Result<variation_File, JsValue> {608        Ok(variation_File { inner: hand::from_js(&data)? })609    }610    /// Writes the File as plain data.611    #[wasm_bindgen(js_name = "toJSON")]612    pub fn to_plain(&self) -> Result<JsValue, JsValue> {613        hand::to_js(&self.inner)614    }615    /// The count of tile repetitions across.616    #[wasm_bindgen(getter)]617    pub fn width(&self) -> Result<usize, JsValue> {618        let value = self.inner.width;619        Ok(value)620    }621    #[wasm_bindgen(setter)]622    pub fn set_width(&mut self, value: usize) -> Result<(), JsValue> {623        self.inner.width = value;624        Ok(())625    }626    /// The count of tile repetitions down.627    #[wasm_bindgen(getter)]628    pub fn height(&self) -> Result<usize, JsValue> {629        let value = self.inner.height;630        Ok(value)631    }632    #[wasm_bindgen(setter)]633    pub fn set_height(&mut self, value: usize) -> Result<(), JsValue> {634        self.inner.height = value;635        Ok(())636    }637    /// The encoded PNG bytes, empty until rendered and left out of the json.638    #[wasm_bindgen(getter)]639    pub fn png(&self) -> Result<Vec<u8>, JsValue> {640        let value = self.inner.png.clone();641        Ok(value)642    }643    #[wasm_bindgen(setter)]644    pub fn set_png(&mut self, value: Vec<u8>) -> Result<(), JsValue> {645        self.inner.png = value;646        Ok(())647    }648    /// Builds a file of the given repetition counts with no PNG bytes.649    #[wasm_bindgen(constructor)]650    pub fn new(width: usize, height: usize) -> Result<variation_File, JsValue> {651        let value = mrlyrs::gen::variation::File::new(width, height);652        Ok(variation_File { inner: value })653    }654}655656/// One seeded artwork, from tile recipe to rendered files.657#[wasm_bindgen]658pub struct variation_Variation {659    inner: mrlyrs::gen::variation::Variation,660}661662#[wasm_bindgen]663impl variation_Variation {664    /// Reads the Variation from its plain data.665    #[wasm_bindgen(js_name = "from")]666    pub fn from_plain(data: JsValue) -> Result<variation_Variation, JsValue> {667        Ok(variation_Variation { inner: hand::from_js(&data)? })668    }669    /// Writes the Variation as plain data.670    #[wasm_bindgen(js_name = "toJSON")]671    pub fn to_plain(&self) -> Result<JsValue, JsValue> {672        hand::to_js(&self.inner)673    }674    /// The random hex identifier.675    #[wasm_bindgen(getter)]676    pub fn key(&self) -> Result<String, JsValue> {677        let value = self.inner.key.clone();678        Ok(value)679    }680    #[wasm_bindgen(setter)]681    pub fn set_key(&mut self, value: String) -> Result<(), JsValue> {682        self.inner.key = value;683        Ok(())684    }685    /// The seed the variation is drawn under.686    #[wasm_bindgen(getter)]687    pub fn seed(&self) -> Result<u64, JsValue> {688        let value = self.inner.seed;689        Ok(value)690    }691    #[wasm_bindgen(setter)]692    pub fn set_seed(&mut self, value: JsValue) -> Result<(), JsValue> {693        let value = hand::u64_from_js(&value)?;694        self.inner.seed = value;695        Ok(())696    }697    /// The paint edition.698    #[wasm_bindgen(getter)]699    pub fn edition(&self) -> Result<JsValue, JsValue> {700        let value = self.inner.edition;701        hand::to_js(&value)702    }703    #[wasm_bindgen(setter)]704    pub fn set_edition(&mut self, value: JsValue) -> Result<(), JsValue> {705        let value = hand::from_js::<mrlyrs::core::paint::Edition>(&value)?;706        self.inner.edition = value;707        Ok(())708    }709    /// The primary inks, when the config fixes them.710    #[wasm_bindgen(getter)]711    pub fn primaries(&self) -> Result<JsValue, JsValue> {712        let value = self.inner.primaries.clone();713        hand::to_js(&value)714    }715    #[wasm_bindgen(setter)]716    pub fn set_primaries(&mut self, value: JsValue) -> Result<(), JsValue> {717        let value = hand::from_js::<Option<Vec<mrlyrs::core::paint::Ink>>>(&value)?;718        self.inner.primaries = value;719        Ok(())720    }721    /// The tile recipe.722    #[wasm_bindgen(getter)]723    pub fn tile(&self) -> Result<Tile, JsValue> {724        let value = self.inner.tile.clone();725        Ok(Tile { inner: value })726    }727    #[wasm_bindgen(setter)]728    pub fn set_tile(&mut self, value: &Tile) -> Result<(), JsValue> {729        self.inner.tile = value.inner.clone();730        Ok(())731    }732    /// The mask tile, present only under the Neighbors edition.733    #[wasm_bindgen(getter)]734    pub fn mask(&self) -> Result<Option<Tile>, JsValue> {735        let value = self.inner.mask.clone();736        Ok(value.map(|inner| Tile { inner }))737    }738    #[wasm_bindgen(setter)]739    pub fn set_mask(&mut self, value: JsValue) -> Result<(), JsValue> {740        let value = hand::option_from_js(&value, |x1| hand::from_js::<mrlyrs::gen::Tile>(&hand::plain(x1)?))?;741        self.inner.mask = value;742        Ok(())743    }744    /// The built base cell, set by generate and left out of the json.745    #[wasm_bindgen(getter)]746    pub fn base(&self) -> Result<JsValue, JsValue> {747        let value = self.inner.base.clone();748        hand::option_to_js(value.as_ref(), hand::cell2d_to_js)749    }750    #[wasm_bindgen(setter)]751    pub fn set_base(&mut self, value: JsValue) -> Result<(), JsValue> {752        let value = hand::option_from_js(&value, hand::cell2d_from_js)?;753        self.inner.base = value;754        Ok(())755    }756    /// The renderings, filled by render.757    #[wasm_bindgen(getter)]758    pub fn files(&self) -> Result<JsValue, JsValue> {759        let value = self.inner.files.clone();760        hand::list_to_js(&value, |x1| Ok(JsValue::from(variation_File { inner: x1.clone() })))761    }762    #[wasm_bindgen(setter)]763    pub fn set_files(&mut self, value: JsValue) -> Result<(), JsValue> {764        let value = hand::list_from_js(&value, |x1| hand::from_js::<mrlyrs::gen::variation::File>(&hand::plain(x1)?))?;765        self.inner.files = value;766        Ok(())767    }768    /// Returns whether the edition paints the whole tiled canvas.769    pub fn is_cover(&self) -> Result<bool, JsValue> {770        let value = self.inner.is_cover();771        Ok(value)772    }773    /// Returns whether the edition paints the base cell before tiling.774    pub fn is_prime(&self) -> Result<bool, JsValue> {775        let value = self.inner.is_prime();776        Ok(value)777    }778}779780/// The five construction families a tile can belong to.781#[wasm_bindgen]782pub struct Group {}783784#[wasm_bindgen]785impl Group {786    /// Returns every Group in canonical order.787    pub fn all() -> Result<JsValue, JsValue> {788        let value = mrlyrs::gen::Group::all();789        hand::to_js(&value)790    }791}792793/// The parity filter over candidate sizes.794#[wasm_bindgen]795pub struct Parity {}796797#[wasm_bindgen]798impl Parity {799    /// Returns every Parity in canonical order.800    pub fn all() -> Result<JsValue, JsValue> {801        let value = mrlyrs::gen::Parity::all();802        hand::to_js(&value)803    }804    /// Returns true when the number passes the filter.805    pub fn keep(parity: JsValue, n: usize) -> Result<bool, JsValue> {806        let parity = hand::from_js::<mrlyrs::gen::Parity>(&parity)?;807        let value = parity.keep(n);808        Ok(value)809    }810}811812/// The constraints a random flat tile is drawn under.813#[wasm_bindgen]814pub struct build_Config2d {}815816#[wasm_bindgen]817impl build_Config2d {818    /// Returns the default Config2d.819    #[wasm_bindgen(js_name = "default")]820    pub fn default_() -> Result<JsValue, JsValue> {821        let value = mrlyrs::gen::build::Config2d::default();822        hand::to_js(&value)823    }824}825826/// The constraints a random cube tile is drawn under, shared by the hex pipeline.827#[wasm_bindgen]828pub struct build_Config3d {}829830#[wasm_bindgen]831impl build_Config3d {832    /// Returns the default Config3d.833    #[wasm_bindgen(js_name = "default")]834    pub fn default_() -> Result<JsValue, JsValue> {835        let value = mrlyrs::gen::build::Config3d::default();836        hand::to_js(&value)837    }838}839840/// One value for every slot of a tile, or one value per slot.841#[wasm_bindgen]842pub struct name_Slots {}843844#[wasm_bindgen]845impl name_Slots {846    /// Returns the default Slots.847    #[wasm_bindgen(js_name = "default")]848    pub fn default_() -> Result<JsValue, JsValue> {849        let value = mrlyrs::gen::name::Slots::default();850        hand::to_js(&value)851    }852}853854/// The named designs a source can point at: the four classics and their four antis.855#[wasm_bindgen]856pub struct recipe_Design {}857858#[wasm_bindgen]859impl recipe_Design {860    /// Returns every Design in canonical order.861    pub fn all() -> Result<JsValue, JsValue> {862        let value = mrlyrs::gen::recipe::Design::all();863        hand::to_js(&value)864    }865}866867/// The settings an artwork is drawn under.868#[wasm_bindgen]869pub struct variation_Config {}870871#[wasm_bindgen]872impl variation_Config {873    /// Returns the default Config.874    #[wasm_bindgen(js_name = "default")]875    pub fn default_() -> Result<JsValue, JsValue> {876        let value = mrlyrs::gen::variation::Config::default();877        hand::to_js(&value)878    }879}