Closed Geolykt closed 2 years ago
Unlike vault, Treasury provides multi-currency support. Given that this multi-currency support is a thing in the backend, API users may be tempted to expose currencies to the frontend. Implementing
/balance
is implemented easily, albeit expensively by iterating over each and every currency and doing other trivial operations. However commands such as/pay
would be a lot more complicated to implement as now you'd have to parse the amount. It is rather easy if you have a syntax that operates like/pay <reciever> <amount> [currency]
, where as currency has to be a currency name; easy enough to implement given that the currencies name can be looked up easily via Treasury API. However what if the User wants to format the amount to something like15€
? As far as I see there is no sane API to resolve that currency. The same applies to$ 15
,$15
,15 USD
or15 €
. An API user would not like to do this parsing hell manually so I propose an API to allow parsing strings such as the previous examples. This is aided by the fact that Currencies are only provided by the economy provider, so 3rd party currencies would not prove to be much of an issue.What would the best course of action be here?
Currency#formatBalance
- is this what you are looking for? Or something else? :)
Unlike vault, Treasury provides multi-currency support. Given that this multi-currency support is a thing in the backend, API users may be tempted to expose currencies to the frontend. Implementing
/balance
is implemented easily, albeit expensively by iterating over each and every currency and doing other trivial operations. However commands such as/pay
would be a lot more complicated to implement as now you'd have to parse the amount. It is rather easy if you have a syntax that operates like/pay <reciever> <amount> [currency]
, where as currency has to be a currency name; easy enough to implement given that the currencies name can be looked up easily via Treasury API. However what if the User wants to format the amount to something like15€
? As far as I see there is no sane API to resolve that currency. The same applies to$ 15
,$15
,15 USD
or15 €
. An API user would not like to do this parsing hell manually so I propose an API to allow parsing strings such as the previous examples. This is aided by the fact that Currencies are only provided by the economy provider, so 3rd party currencies would not prove to be much of an issue. What would the best course of action be here?
Currency#formatBalance
- is this what you are looking for? Or something else? :)
I think he refers to a player doing something like /pay lokka30 30€
or /pay lokka30 30$
. The player may write that instead of /pay lokka30 30 euro
or /pay lokka30 30 dolar
or /pay lokka30 30 euros
or /pay lokka30 30 dolars
Unlike vault, Treasury provides multi-currency support. Given that this multi-currency support is a thing in the backend, API users may be tempted to expose currencies to the frontend. Implementing
/balance
is implemented easily, albeit expensively by iterating over each and every currency and doing other trivial operations. However commands such as/pay
would be a lot more complicated to implement as now you'd have to parse the amount. It is rather easy if you have a syntax that operates like/pay <reciever> <amount> [currency]
, where as currency has to be a currency name; easy enough to implement given that the currencies name can be looked up easily via Treasury API. However what if the User wants to format the amount to something like15€
? As far as I see there is no sane API to resolve that currency. The same applies to$ 15
,$15
,15 USD
or15 €
. An API user would not like to do this parsing hell manually so I propose an API to allow parsing strings such as the previous examples. This is aided by the fact that Currencies are only provided by the economy provider, so 3rd party currencies would not prove to be much of an issue. What would the best course of action be here?
Currency#formatBalance
- is this what you are looking for? Or something else? :)I think he refers to a player doing something like
/pay lokka30 30€
or/pay lokka30 30$
. The player may write that instead of/pay lokka30 30 euro
or/pay lokka30 30 dolar
or/pay lokka30 30 euros
or/pay lokka30 30 dolars
Shouldn't the economy provider handle all of that? Or do you also want a method in Treasury for other plugins to put in a String and get a Double, Currency out?
There is 0 point in having it being implementation-specific API, let's say I have a bank plugin where people get interest on their money they deposit. I would need to query each and every implementation I know of in order to implement the commands. This defeats the whole point of using an API to begin with
It should be a feature within the Treasury API. To parse a String into a Currency and Double.
I have an idea in my head about doing the code of parsing currency symbols and such into 2 objects with a combined result object, but I'll wait on #37 to be pulled. :)
I have an idea in my head about doing the code of parsing currency symbols and such into 2 objects with a combined result object, but I'll wait on #37 to be pulled. :)
I suppose some regex must be used here. We can match for the number part and then search in the remaining string for names/symbols
this is what I've written for ~30 minutes.
```java
package com.mrivanplays;
import com.mrivanplays.ParsingTest.ParseResult.State;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ParsingTest {
// stfu I couldn't name it otherwise and this is an example so stfu
public static record WaysToTypeCurrency(char byChar, String byCountryCode) {}
// assume this is the plugin's logic of handling currencies
// i cba to make it better just for an example
public static class CurrencyRegistrar {
private Map
Currently not at it's best, my results show that it can't parse double values properly although I added a special case for them. Not anymore. Edited with working code.
I suppose Currency#getAliases
would be useful here
I will also try to write something latter
I suppose
Currency#getAliases
would be useful here I will also try to write something latter
my example is plain java the reason why i dont use plugin specific methods in it and create some stuff by myself.
I'd like if that parser would be changeable (even if it is only changeable for the economy provider) as I'd want to have a much more overkill solution to this problem
I'd like if that parser would be changeable (even if it is only changeable for the economy provider) as I'd want to have a much more overkill solution to this problem
wait a minute so you want a solution integrated into treasury yet you want it to run with a different logic with what is (going to be) implemented !? why don't you just parse it yourself? in such case use my code and adapt it to work with treasury's currency registrar and your problem is basically solved.
I'd like if that parser would be changeable (even if it is only changeable for the economy provider) as I'd want to have a much more overkill solution to this problem
wait a minute so you want a solution integrated into treasury yet you want it to run with a different logic with what is (going to be) implemented !? why don't you just parse it yourself? in such case use my code and adapt it to work with treasury's currency registrar and your problem is basically solved.
A solution for the parser. A plugin that manages all the currencies (the provider) may want to use its own parser, but a plugin that adds a /pay
command, he just doesn't care, might use the default one or whatever
I've came up with this, if someone wants to review it
@MrNemo64 nice one! We can do a combination of mine and your solution and it will be perfect. I'll write such tomorrow.
I think this is the best of both mine and @MrNemo64's version:
I think this is the best of both worlds (my first and @MrNemo64 's version)
```java
package com.mrivanplays;
import com.mrivanplays.ParsingTest.ParseResult.State;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ParsingTest {
// stfu I couldn't name it otherwise and this is an example so stfu
public static record WaysToTypeCurrency(char byChar, String byCountryCode) {}
// a way to store multiple names easy in a map
public static record AcceptableCurrencyNames(String... names) {
public String base() {
return names[0];
}
}
// assume this is the plugin's logic of handling currencies
// i cba to make it better just for an example
public static class CurrencyRegistrar {
private Map
Result:
How would this code work with inputs like "1.56.7 euro" or "1e2u3r4o"
Oh fuck forgot to add detection for multiple dots... will add this l8r
"1e2u3r4o"
Surely, that's beyond the scope of this issue :smile: of course no worries if it is implemented but I don't think anyone should bother making an algorithm that works with that
"1e2u3r4o"
Surely, that's beyond the scope of this issue :smile: of course no worries if it is implemented but I don't think anyone should bother making an algorithm that works with that
Actually thats pretty simple to parse and it is already implemented in my code.
"1e2u3r4o"
Surely, that's beyond the scope of this issue 😄 of course no worries if it is implemented but I don't think anyone should bother making an algorithm that works with that
Actually thats pretty simple to parse and it is already implemented in my code.
If I'm not mistaken your code would parse it like 1234 ( currency: euro )
and, in my opinion, anything that doesn't match ammount currency or currency ammount should not parse
We need @lokka30 's opinion about whether to only parse 'currency amount' or 'amount currency' (space (in/ex)cluded) or in any way it can.
@MrNemo64 turning on the computer and I have an idea about it. What if we create a custom pattern class specifically about parsing such values? That way developers will be able to choose whether to support currency value
, value currency
, both, everything or a custom pattern.
On the other hand tho, this makes this API kinda bloated, but we can specify it to parse everything by default.
Now invalidates values with more than 1 dot
```java
package com.mrivanplays;
import com.mrivanplays.ParsingTest.ParseResult.State;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ParsingTest {
// stfu I couldn't name it otherwise and this is an example so stfu
public static record WaysToTypeCurrency(char byChar, String byCountryCode) {}
// a way to store multiple names easy in a map
public static record AcceptableCurrencyNames(String... names) {
public String base() {
return names[0];
}
}
// assume this is the plugin's logic of handling currencies
// i cba to make it better just for an example
public static class CurrencyRegistrar {
private Map
In this test version I also replaced State.FAILURE with more descriptive enum constants.
A small layer of safety can do no harm, but I don't think that "1e2u3r4o" should not error out.
@MrNemo64 turning on the computer and I have an idea about it. What if we create a custom pattern class specifically about parsing such values? That way developers will be able to choose whether to support
currency value
,value currency
, both, everything or a custom pattern.
Sorry for late response, was bussy. I don't see much use in that. Take england for example, they write currency value : £20 £60, so if a server has the pound as currency they will most likely use that format, in other places you put first the value then the currency: 9€ So just allowing one doesn't feel right
I mean we can make it so that multiple patterns can be inserted.
I supose, but having already some functions that parse strings into ammount an currency why do this? The implementing plugin shouldn't have to worry about parsing, that's what the method is for, so why make the pattern, it gives the idea that you have to worry about it
It won't be mandatory to do that. We will have a couple of default patterns that will be specified when a method which doesn't accept them is called.
So we can have
parse(String foo, ParsePattern... patterns)
and
parse(String foo)
We can also make it so that the default patterns are controllable by the economy provider.
That makes some more sense but how would a ParsePattern look like and why can you specify more than one?
public class ParsePattern {
private final String pattern;
// constructor and getter and other helpful methods perhaps
}
And on the parse method we could do something like
public /* insert return object here */ parse(String val, ParsePattern... patterns) {
for (var patternObj : patterns) {
var pattern = patternObj.getPattern();
if (pattern.startsWith("%c") {
// first read the currency, then the value
} else if (pattern.startsWith("%v") {
// first read the value, then the currency
}
// of course if the pattern doesn't match we can call continue and go to the
// next one if there is such.
}
}
This is just an example it shouldn't be thought of as a final version. Pretty sure I can think of something a little bit more robust whenever it comes to implementing that.
I see now. So maybe if someone only wants the ammount they can do pattern=%v
, only the currency pattern=%c
currency and value no matter the order maybe pattern=%c%v%c
or something like that. Maybe instead of ParsePatten having a pattern object we can make it so it's kinda like a Function<String, CurrencyAndAmmount>
and provide default implementations for some common uses. For example
CurrencyParsePattern.AMMOUNT_ONLY
would be a Function<String, Double>
and only extracts the ammount
CurrencyParsePattern.CURRENCY_ONLY
would be a Function<String, Currency>
and only extracts the currency
CurrencyParsePattern.AMMOUNT_AND_CURRENCY
would be a Function<String, AmmountAndCurrency (dont know how to call it)>
and extracts both
We'll think how it will be the best both for the economy provider and the developer utilizing the economy provider.
Maybe in the EconomyProvider interface there is default method for these so the implementation can change them if it wants @Geolykt was concerned about this
It's been 1 month with no activity on this so... What shall we do? parse patterns or have it hardcoded like the example above?
It's been 1 month with no activity on this so... What shall we do? parse patterns or have it hardcoded like the example above?
Seeing what you said in #49 it may be better to wait
Unlike vault, Treasury provides multi-currency support. Given that this multi-currency support is a thing in the backend, API users may be tempted to expose currencies to the frontend. Implementing
/balance
is implemented easily, albeit expensively by iterating over each and every currency and doing other trivial operations. However commands such as/pay
would be a lot more complicated to implement as now you'd have to parse the amount. It is rather easy if you have a syntax that operates like/pay <reciever> <amount> [currency]
, where as currency has to be a currency name; easy enough to implement given that the currencies name can be looked up easily via Treasury API. However what if the User wants to format the amount to something like15€
? As far as I see there is no sane API to resolve that currency. The same applies to$ 15
,$15
,15 USD
or15 €
. An API user would not like to do this parsing hell manually so I propose an API to allow parsing strings such as the previous examples. This is aided by the fact that Currencies are only provided by the economy provider, so 3rd party currencies would not prove to be much of an issue.What would the best course of action be here?