feather-rs / lieutenant

Command dispatcher for Rust based on Mojang's Brigadier
Apache License 2.0
1 stars 4 forks source link

Parser modifier feature request. #15

Open Miro-Andrin opened 4 years ago

Miro-Andrin commented 4 years ago

The commands.json file describes parsers as a combination of a base parsers plus a modifier. Some examples:


"parser": "minecraft:entity",
"properties": {
                "amount": "single",
                "type": "entities"
 }

"parser": "minecraft:entity",
"properties": {
            "amount": "multiple",
            "type": "entities"
 },

"parser": "brigadier:integer",
"properties": {
             "min": 1,
             "max": 1000000
 }

When i am trying to generate rust/lieutenant code i need to work around this, because lieutenant does not sport properties/modifiers. As a hacky solution i treat every combination of "parser" + "properties" as a unique parser. This works but is not elegant.

A list of every parser referenced in commands.json, as of Minecraft 1.16:

brigadier:bool
brigadier:double
brigadier:float{'min': -60000000.0, 'max': 60000000.0}
brigadier:float{'min': 0.0, 'max': 1.0}
brigadier:float{'min': 0.0, 'max': 2.0}
brigadier:float{'min': 0.0}
brigadier:float{'min': 1.0}
brigadier:integer
brigadier:integer{'min': 0, 'max': 1000000}
brigadier:integer{'min': 0, 'max': 255}
brigadier:integer{'min': 0, 'max': 65535}
brigadier:integer{'min': 0}
brigadier:integer{'min': 1, 'max': 1000000}
brigadier:integer{'min': 1, 'max': 64}
brigadier:integer{'min': 1}
brigadier:string{'type': 'greedy'}
brigadier:string{'type': 'phrase'}
brigadier:string{'type': 'word'}
minecraft:angle
minecraft:block_pos
minecraft:block_predicate
minecraft:block_state
minecraft:color
minecraft:column_pos
minecraft:component
minecraft:dimension
minecraft:entity_anchor
minecraft:entity_summon
minecraft:entity{'amount': 'multiple', 'type': 'entities'}
minecraft:entity{'amount': 'multiple', 'type': 'players'}
minecraft:entity{'amount': 'single', 'type': 'entities'}
minecraft:entity{'amount': 'single', 'type': 'players'}
minecraft:function
minecraft:game_profile
minecraft:int_range
minecraft:item_enchantment
minecraft:item_predicate
minecraft:item_slot
minecraft:item_stack
minecraft:message
minecraft:mob_effect
minecraft:nbt_compound_tag
minecraft:nbt_path
minecraft:nbt_tag
minecraft:objective
minecraft:objective_criteria
minecraft:operation
minecraft:particle
minecraft:resource_location
minecraft:rotation
minecraft:score_holder{'amount': 'multiple'}
minecraft:score_holder{'amount': 'single'}
minecraft:scoreboard_slot
minecraft:swizzle
minecraft:team
minecraft:time
minecraft:uuid
minecraft:vec2 
minecraft:vec3

As you can see most of the parsers that have a modifier are actually the numeric types, so if a generic solution is not wanted, or is to much of a hassle, then at least consider adding it for the numeric types. However the generic solution would be appreciated.

Defman commented 4 years ago

I think we should leave this until const generics are stabilized, we can then do parser::<Range<i32, 0, 100>>(). Right now we can do this, however, it requires a custom type for all ranges.

Defman commented 4 years ago

There's also the option

fn range<T, P<T>>(parser: P, min: T, max: T) -> impl Parser where
  T: std::cmp::Ord,
  P: Parser<T>;

range(parser::<i32>(), 0, 100)