Exemple #1
0
        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="provider">The underlying value provider.</param>
        public GenericToken(IValueProvider provider)
        {
            this.Values = provider;

            this.Name = TokenName.Parse(provider.Name);
            this.CanHaveMultipleRootValues = provider.CanHaveMultipleValues();
        }
Exemple #2
0
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 /// <param name="values">Get the current token values.</param>
 /// <param name="allowedValues">The allowed values (or <c>null</c> if any value is allowed).</param>
 /// <param name="canHaveMultipleValues">Whether the token may contain multiple values (or <c>null</c> to set it based on the given values).</param>
 public ImmutableToken(TokenName name, InvariantHashSet values, InvariantHashSet allowedValues = null, bool?canHaveMultipleValues = null)
     : base(name, canHaveMultipleRootValues: false)
 {
     this.Values                    = values ?? new InvariantHashSet();
     this.AllowedRootValues         = allowedValues;
     this.CanHaveMultipleRootValues = canHaveMultipleValues ?? (this.Values.Count > 1 || this.AllowedRootValues == null || this.AllowedRootValues.Count > 1);
     this.EnableSubkeys(required: false, canHaveMultipleValues: false);
     this.IsValidInContext = true;
 }
Exemple #3
0
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check, if applicable.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or this token require a subkeys and <paramref name="name"/> does not specify one.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (this.Values.TryGetValue(name.Subkey, out string value))
            {
                yield return(value);
            }
        }
Exemple #4
0
        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="provider">The underlying value provider.</param>
        public GenericToken(IValueProvider provider)
        {
            this.Values = provider;

            this.Name                      = TokenName.Parse(provider.Name);
            this.CanHaveSubkeys            = provider.AllowsInput;
            this.RequiresSubkeys           = provider.RequiresInput;
            this.CanHaveMultipleRootValues = provider.CanHaveMultipleValues();
            this.IsValidInContext          = provider.IsValidInContext;
        }
Exemple #5
0
 /// <summary>Get the allowed values for a token name (or <c>null</c> if any value is allowed).</summary>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public override InvariantHashSet GetAllowedValues(TokenName name)
 {
     if (name.HasSubkey())
     {
         return new InvariantHashSet {
                    true.ToString(), false.ToString()
         }
     }
     ;
     return(this.AllowedRootValues);
 }
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (name.HasSubkey())
            {
                return new[] { this.Values.Contains(name.Subkey).ToString() }
            }
            ;
            return(this.Values);
        }
    }
Exemple #7
0
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (name.HasSubkey())
            {
                bool hasProfession = this.TryParseEnum(name.Subkey, out Profession profession, mustBeNamed: false) && this.Professions.Contains(profession);
                yield return(hasProfession.ToString());
            }
            else
            {
                foreach (Profession profession in this.Professions)
                {
                    yield return(profession.ToString());
                }
            }
        }
Exemple #8
0
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (name.HasSubkey())
            {
                if (this.Values.TryGetValue(name.Subkey, out string value))
                {
                    yield return(value);
                }
            }
            else
            {
                foreach (var pair in this.Values)
                {
                    yield return($"{pair.Key}:{pair.Value}");
                }
            }
        }
Exemple #9
0
        /// <summary>Perform custom validation on a subkey/value pair.</summary>
        /// <param name="name">The token name to validate.</param>
        /// <param name="value">The value to validate.</param>
        /// <param name="error">The validation error, if any.</param>
        /// <returns>Returns whether validation succeeded.</returns>
        public override bool TryValidate(TokenName name, string value, out string error)
        {
            if (!base.TryValidate(name, value, out error))
            {
                return(false);
            }

            // validate profession IDs
            string profession = name.HasSubkey() ? name.Subkey : value;

            if (!this.TryParseEnum(profession, out Profession _, mustBeNamed: false))
            {
                error = $"can't parse '{profession}' as a profession ID; must be one of [{string.Join(", ", Enum.GetNames(typeof(Profession)).OrderByIgnoreCase(p => p))}] or an integer ID.";
                return(false);
            }

            error = null;
            return(true);
        }
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (name.HasSubkey())
            {
                if (this.TryParseEnum(name.Subkey, out Skill skill) && this.SkillLevels.TryGetValue(skill, out int level))
                {
                    yield return(level.ToString());
                }
            }
            else
            {
                foreach (var pair in this.SkillLevels)
                {
                    yield return($"{pair.Key}:{pair.Value}");
                }
            }
        }
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            if (name.HasSubkey())
            {
                bool hasItem = this.TryParseEnum(name.Subkey, out WalletItem item) && this.WalletItems[item]();
                yield return(hasItem.ToString());
            }
            else
            {
                foreach (KeyValuePair <WalletItem, Func <bool> > pair in this.WalletItems)
                {
                    if (pair.Value())
                    {
                        yield return(pair.Key.ToString());
                    }
                }
            }
        }
Exemple #12
0
 /// <summary>Perform custom validation on a subkey/value pair.</summary>
 /// <param name="name">The token name to validate.</param>
 /// <param name="value">The value to validate.</param>
 /// <param name="error">The validation error, if any.</param>
 /// <returns>Returns whether validation succeeded.</returns>
 public virtual bool TryValidate(TokenName name, string value, out string error)
 {
     error = null;
     return(true);
 }
Exemple #13
0
 /// <summary>Get the allowed values for a token name (or <c>null</c> if any value is allowed).</summary>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public virtual InvariantHashSet GetAllowedValues(TokenName name)
 {
     return(this.Values.GetAllowedValues(name.Subkey));
 }
Exemple #14
0
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 /// <param name="canHaveMultipleValues">Whether the token may contain multiple values (or <c>null</c> to set it based on the given values).</param>
 /// <param name="allowedValues">The allowed values (or <c>null</c> if any value is allowed).</param>
 /// <param name="values">Get the current token values.</param>
 public ImmutableToken(string name, InvariantHashSet values, InvariantHashSet allowedValues = null, bool?canHaveMultipleValues = null)
     : this(TokenName.Parse(name), values, allowedValues, canHaveMultipleValues)
 {
 }
Exemple #15
0
 /// <summary>Get the current token values.</summary>
 /// <param name="name">The token name to check.</param>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public virtual IEnumerable <string> GetValues(TokenName name)
 {
     this.AssertTokenName(name);
     return(this.Values.GetValues(name.Subkey));
 }
Exemple #16
0
 /// <summary>Whether the token may return multiple values for the given name.</summary>
 /// <param name="name">The token name.</param>
 public bool CanHaveMultipleValues(TokenName name)
 {
     return(this.Values.CanHaveMultipleValues(name.Subkey));
 }
 /// <summary>Get the allowed values for a token name (or <c>null</c> if any value is allowed).</summary>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public override InvariantHashSet GetAllowedValues(TokenName name)
 {
     return(name.HasSubkey()
         ? InvariantHashSet.Boolean()
         : this.AllowedRootValues);
 }
Exemple #18
0
 /// <summary>Whether the token may return multiple values for the given name.</summary>
 /// <param name="name">The token name.</param>
 public bool CanHaveMultipleValues(TokenName name)
 {
     return(name.HasSubkey()
         ? this.CanHaveMultipleSubkeyValues
         : this.CanHaveMultipleRootValues);
 }
Exemple #19
0
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 /// <param name="canHaveMultipleRootValues">Whether the root token may contain multiple values.</param>
 protected BaseToken(string name, bool canHaveMultipleRootValues)
     : this(TokenName.Parse(name), canHaveMultipleRootValues)
 {
 }
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="key">The name of the token whose value to set.</param>
 /// <param name="value">The token value to set.</param>
 /// <param name="conditions">The conditions that must match to set this value.</param>
 public DynamicTokenValue(TokenName key, InvariantHashSet value, ConditionDictionary conditions)
 {
     this.Name       = key;
     this.Value      = value;
     this.Conditions = conditions;
 }
Exemple #21
0
        /// <summary>Get the current token values.</summary>
        /// <param name="name">The token name to check.</param>
        /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
        public override IEnumerable <string> GetValues(TokenName name)
        {
            this.AssertTokenName(name);

            yield return(this.GetPathExists(name.Subkey).ToString());
        }
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 public DynamicToken(TokenName name)
     : base(new DynamicTokenValueProvider(name.Key))
 {
     this.DynamicValues = (DynamicTokenValueProvider)base.Values;
 }
Exemple #23
0
        /// <summary>Perform custom validation.</summary>
        /// <param name="name">The token name to validate.</param>
        /// <param name="values">The values to validate.</param>
        /// <param name="error">The validation error, if any.</param>
        /// <returns>Returns whether validation succeeded.</returns>
        public bool TryValidate(TokenName name, InvariantHashSet values, out string error)
        {
            // parse data
            KeyValuePair <TokenName, string>[] pairs = this.GetSubkeyValuePairsFor(name, values).ToArray();

            // restrict to allowed subkeys
            if (this.CanHaveSubkeys)
            {
                InvariantHashSet validKeys = this.GetAllowedSubkeys();
                if (validKeys != null)
                {
                    string[] invalidSubkeys =
                        (
                            from pair in pairs
                            where pair.Key.Subkey != null && !validKeys.Contains(pair.Key.Subkey)
                            select pair.Key.Subkey
                        )
                        .Distinct()
                        .ToArray();
                    if (invalidSubkeys.Any())
                    {
                        error = $"invalid subkeys ({string.Join(", ", invalidSubkeys)}); expected one of {string.Join(", ", validKeys)}";
                        return(false);
                    }
                }
            }

            // restrict to allowed values
            {
                InvariantHashSet validValues = this.GetAllowedValues(name);
                if (validValues?.Any() == true)
                {
                    string[] invalidValues =
                        (
                            from pair in pairs
                            where !validValues.Contains(pair.Value)
                            select pair.Value
                        )
                        .Distinct()
                        .ToArray();
                    if (invalidValues.Any())
                    {
                        error = $"invalid values ({string.Join(", ", invalidValues)}); expected one of {string.Join(", ", validValues)}";
                        return(false);
                    }
                }
            }

            // custom validation
            foreach (KeyValuePair <TokenName, string> pair in pairs)
            {
                if (!this.Values.TryValidate(pair.Key.Subkey, new InvariantHashSet {
                    pair.Value
                }, out error))
                {
                    return(false);
                }
            }

            // no issues found
            error = null;
            return(true);
        }
Exemple #24
0
 /// <summary>Get the allowed values for a token name (or <c>null</c> if any value is allowed).</summary>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public virtual InvariantHashSet GetAllowedValues(TokenName name)
 {
     return(null);
 }
 /*********
 ** Public methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 public DynamicToken(TokenName name)
     : base(name, canHaveMultipleRootValues: false)
 {
     this.AllowedRootValues = new InvariantHashSet();
     this.EnableSubkeys(required: false, canHaveMultipleValues: false);
 }
Exemple #26
0
 /// <summary>Get the current token values.</summary>
 /// <param name="name">The token name to check.</param>
 /// <exception cref="InvalidOperationException">The key doesn't match this token, or the key does not respect <see cref="IToken.CanHaveSubkeys"/> or <see cref="IToken.RequiresSubkeys"/>.</exception>
 public virtual IEnumerable <string> GetValues(TokenName name)
 {
     this.AssertTokenName(name);
     yield break;
 }
Exemple #27
0
 /*********
 ** Protected methods
 *********/
 /// <summary>Construct an instance.</summary>
 /// <param name="name">The token name.</param>
 /// <param name="canHaveMultipleRootValues">Whether the root token may contain multiple values.</param>
 protected BaseToken(TokenName name, bool canHaveMultipleRootValues)
 {
     this.Name = name;
     this.CanHaveMultipleRootValues = canHaveMultipleRootValues;
 }
Exemple #28
0
        /// <summary>Get the subkey/value pairs used in the given name and values.</summary>
        /// <param name="name">The token name to validate.</param>
        /// <param name="values">The values to validate.</param>
        /// <returns>Returns the subkey/value pairs found. If the <paramref name="name"/> includes a subkey, the <paramref name="values"/> are treated as values of that subkey. Otherwise if <see cref="CanHaveSubkeys"/> is true, then each value is treated as <c>subkey:value</c> (if they contain a colon) or <c>value</c> (with a null subkey).</returns>
        protected IEnumerable <KeyValuePair <TokenName, string> > GetSubkeyValuePairsFor(TokenName name, InvariantHashSet values)
        {
            // no subkeys in values
            if (!this.CanHaveSubkeys || name.HasSubkey())
            {
                foreach (string value in values)
                {
                    yield return(new KeyValuePair <TokenName, string>(name, value));
                }
            }

            // possible subkeys in values
            else
            {
                foreach (string value in values)
                {
                    string[] parts = value.Split(new[] { ':' }, 2);
                    if (parts.Length < 2)
                    {
                        yield return(new KeyValuePair <TokenName, string>(name, parts[0]));
                    }
                    else
                    {
                        yield return(new KeyValuePair <TokenName, string>(new TokenName(name.Key, parts[0]), parts[1]));
                    }
                }
            }
        }