tinkoff-mobile-tech / decoro

Android library designed for automatic formatting of text input by custom rules
Apache License 2.0
391 stars 31 forks source link

Russian number in next format +8 937 333 22 22 #17

Closed Pahanuch closed 7 years ago

Pahanuch commented 7 years ago

Hi. We can have phone number in next format +8 937 333 22 22. What we must to do, that our mask suppor all possible formats ?

Vittt2008 commented 7 years ago

Hi, @Pahanuch I'm afraid you have a mistake because all russian numbers start with +7 or 8. I can't find any Russian number, witch starts with +8. The current version of this library doesn't support multiple mask for one field, but you can change it dynamically by yourself. If you want create this mask you can use UnderscoreDigitSlotsParser.

SlotsParser slotsParser = new UnderscoreDigitSlotsParser();
MaskImpl maskDescriptor = MaskImpl.createTerminated(slotsParser.parseSlots("+8 ___ ___ __ __"));
Vittt2008 commented 7 years ago

Or you can create your own implementation of SlotParser. This is example of SlotParser with Alphabet.

public class ExtendedSlotParser implements SlotsParser {

    public static class Alphabet {
        private static final char ANYTHING_KEY = '*';
        private static final char DIGIT_KEY = '#';
        private static final char UPPERCASE_KEY = 'U';
        private static final char LOWERCASE_KEY = 'L';
        private static final char ALPHA_NUMERIC_KEY = 'A';
        private static final char LETTER_KEY = '?';
    }

    @NonNull
    @Override
    public Slot[] parseSlots(@NonNull CharSequence rawMask) {
        if (TextUtils.isEmpty(rawMask)) {
            throw new IllegalArgumentException("String representation of the mask's slots is empty");
        }

        final Slot[] result = new Slot[rawMask.length()];
        for (int index = 0; index < rawMask.length(); index++) {
            final char currentChar = rawMask.charAt(index);
            result[index] = slotFromChar(currentChar);
        }

        return result;
    }

    protected Slot slotFromChar(final char character) {
        switch (character) {
            case Alphabet.ANYTHING_KEY:
                return PredefinedSlots.any();
            case Alphabet.DIGIT_KEY:
                return PredefinedSlots.digit();
            case Alphabet.UPPERCASE_KEY:
                return PredefinedSlots.letterUpperCase();
            case Alphabet.LOWERCASE_KEY:
                return PredefinedSlots.letterLowerCase();
            case Alphabet.ALPHA_NUMERIC_KEY:
                return PredefinedSlots.digitOrLetter();
            case Alphabet.LETTER_KEY:
                return PredefinedSlots.letter();
            default:
                return PredefinedSlots.hardcodedSlot(character);
        }
    }
}
public final class PredefinedSlots {

    public static Slot hardcodedSlot(char value) {
        return new Slot(Slot.RULES_HARDCODED, value, null);
    }

    public static Slot digit() {
        return new Slot(null, new SlotValidators.DigitValidator());
    }

    public static Slot any() {
        return new Slot(null, new SlotValidators.GenerousValidator());
    }

    public static Slot letter() {
        return new Slot(null, new SlotValidators.LetterValidator());
    }

    public static Slot letterUpperCase() {
        Slot slot = letter();
        slot.setValueInterpreter(new ValueInterpreter() {
            @Override
            public Character interpret(Character character) {
                if (character == null) {
                    return null;
                }
                return Character.toUpperCase(character);
            }
        });
        return slot;
    }

    public static Slot letterLowerCase() {
        Slot slot = letter();
        slot.setValueInterpreter(new ValueInterpreter() {
            @Override
            public Character interpret(Character character) {
                if (character == null) {
                    return null;
                }
                return Character.toLowerCase(character);
            }
        });
        return slot;
    }

    public static Slot digitOrLetter() {
        SlotValidatorSet validators = SlotValidatorSet.setOf(new SlotValidators.DigitValidator(), new SlotValidators.LetterValidator());
        return new Slot(null, validators);
    }

    public static Slot maskableDigit() {
        return new Slot(null, new SlotValidators.MaskedDigitValidator());
    }
}