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}