Example #1
0
        public void IgnoreDuplicateSymbols(string symbol)
        {
            var duplicate = $"{symbol}_dupe";

            var schema = new EnumSchema("test");

            Assert.Empty(schema.Symbols);

            schema.Symbols.Add(duplicate);
            Assert.Equal(new[] { duplicate }, schema.Symbols);

            schema.Symbols.Add(symbol);
            Assert.Equal(new[] { duplicate, symbol }, schema.Symbols);

            schema.Symbols.Add(duplicate);
            Assert.Equal(new[] { duplicate, symbol }, schema.Symbols);

            schema.Symbols = new[] { duplicate, duplicate, duplicate };
            Assert.Equal(new[] { duplicate }, schema.Symbols);
        }
        /// <summary>
        /// Generates a compilation unit (essentially a single .cs file) that contains types that
        /// match the schema.
        /// </summary>
        /// <param name="schema">
        /// The schema to generate code for. Code can only be generated for enum
        /// and record schemas.
        /// </param>
        /// <returns>
        /// A compilation unit containing types that match the schema.
        /// </returns>
        /// <throws cref="UnsupportedSchemaException">
        /// Thrown when the schema is not an enum or record, or when a record
        /// field schema is not recognized.
        /// </throws>
        public virtual CompilationUnitSyntax GenerateCompilationUnit(Schema schema)
        {
            var candidates = GetCandidateSchemas(schema)
                             .OrderBy(s => s.Name)
                             .GroupBy(s => s.Namespace)
                             .OrderBy(g => g.Key);

            if (candidates.Count() < 1)
            {
                throw new UnsupportedSchemaException(schema, $"Code can only be generated for enums and records.");
            }

            var unit = SyntaxFactory.CompilationUnit();

            foreach (var group in candidates)
            {
                var members = group
                              .Select(candidate => candidate switch
                {
                    EnumSchema enumSchema => GenerateEnum(enumSchema) as MemberDeclarationSyntax,
                    RecordSchema recordSchema => GenerateClass(recordSchema) as MemberDeclarationSyntax,
                    _ => default,
Example #3
0
        public void EnumCode(EnumSchema enumSchema, string expectedName, string expectedNamespace, string[] expectedSymbols, string expectedDoc, string[] expectedAliases)
        {
            var assembly = CodeGen.Compile(Guid.NewGuid().ToString(), enumSchema, out var xmlDocument);

            var type = assembly.ExportedTypes.FirstOrDefault(r => r.Name == expectedName);

            Assert.NotNull(type);
            Assert.IsTrue(type.IsEnum);
            Assert.AreEqual(expectedNamespace, type.Namespace);

            var symbols = Enum.GetNames(type);

            Assert.AreEqual(expectedSymbols, symbols);

            var doc = GetSummaryText(xmlDocument, type.FullName);

            Assert.AreEqual(expectedDoc, doc);

            var aliases = GetAliasList(xmlDocument, type.FullName);

            Assert.AreEqual(expectedAliases, aliases);
        }
Example #4
0
 public GenericEnum(EnumSchema schema, string value)
 {
     this.Schema = schema;
     this.Value = value;
 }
 protected abstract EnumAccess GetEnumAccess(EnumSchema readerSchema);
Example #6
0
        public void RecordWithMissingFields()
        {
            var boolean = new BooleanSchema();
            var array   = new ArraySchema(boolean);
            var map     = new MapSchema(new IntSchema());
            var @enum   = new EnumSchema("Ordinal", new[] { "None", "First", "Second", "Third", "Fourth" });
            var union   = new UnionSchema(new Schema[]
            {
                new NullSchema(),
                array,
            });

            var schema = new RecordSchema("AllFields")
            {
                Fields = new[]
                {
                    new RecordField("First", union),
                    new RecordField("Second", union),
                    new RecordField("Third", array),
                    new RecordField("Fourth", array),
                    new RecordField("Fifth", map),
                    new RecordField("Sixth", map),
                    new RecordField("Seventh", @enum),
                    new RecordField("Eighth", @enum),
                },
            };

            var deserialize = deserializerBuilder.BuildDelegate <WithoutEvenFields>(schema);
            var serialize   = serializerBuilder.BuildDelegate <WithEvenFields>(schema);

            var value = new WithEvenFields()
            {
                First = new List <bool>()
                {
                    false
                },
                Second = new List <bool>()
                {
                    false, false
                },
                Third = new List <bool>()
                {
                    false, false, false
                },
                Fourth = new List <bool>()
                {
                    false
                },
                Fifth = new Dictionary <string, int>()
                {
                    { "first", 1 }
                },
                Sixth = new Dictionary <string, int>()
                {
                    { "first", 1 }, { "second", 2 }
                },
                Seventh = ImplicitEnum.First,
                Eighth  = ImplicitEnum.None,
            };

            using (stream)
            {
                serialize(value, new Utf8JsonWriter(stream));
            }

            var reader = new Utf8JsonReader(stream.ToArray());

            Assert.Equal(value.Seventh, deserialize(ref reader).Seventh);
        }
Example #7
0
 public SpecificEnumAccess(EnumSchema schema)
 {
     type = ObjectCreator.Instance.GetType(schema);
 }
 public GenericEnumAccess(EnumSchema schema)
 {
     this.schema = schema;
 }
 protected override EnumAccess GetEnumAccess(EnumSchema readerSchema)
 {
     return(new SpecificEnumAccess());
 }
Example #10
0
        private object ReadEnum(object reuse, EnumSchema enumSchema)
        {
            var enumType = LoadType(enumSchema);

            return(Enum.Parse(enumType, (string)((JValue)reuse).Value, true));
        }
Example #11
0
        /// <summary>
        /// Reads an enum from the given decoder
        /// </summary>
        /// <param name="reuse">object to store data read</param>
        /// <param name="writerSchema">schema of the object that wrote the data</param>
        /// <param name="readerSchema">schema of the object that will store the data</param>
        /// <param name="dec">decoder object that contains the data to be read</param>
        /// <returns>enum value</returns>
        protected override object ReadEnum(object reuse, EnumSchema writerSchema, Schema readerSchema, Decoder dec)
        {
            EnumSchema rs = readerSchema as EnumSchema;

            return(rs.Ordinal(writerSchema[dec.ReadEnum()]));
        }
 private static string GenerateCore(EnumSchema schema, string defaultNamespace, bool forceNamespace)
 {
     return(new EnumTemplate(schema, defaultNamespace, forceNamespace).TransformText());
 }
Example #13
0
        private object ReadEnum(JsonReader jr, EnumSchema enumSchema)
        {
            var enumType = LoadType(enumSchema);

            return(Enum.Parse(enumType, (string)jr.Value, true));
        }
 private void VisitCore(EnumSchema s)
 {
     s.Serializer = new EnumSerializer(s);
 }
Example #15
0
        /// <summary>
        /// Reads an <see cref="EnumSchema" />.
        /// </summary>
        /// <returns>
        /// A successful <see cref="JsonSchemaReaderCaseResult" /> with a <see cref="BytesSchema" />
        /// or <see cref="FixedSchema" /> if <paramref name="element" /> is a bytes or fixed schema
        /// with a decimal logical type; an unsuccessful <see cref="JsonSchemaReaderCaseResult" />
        /// with an <see cref="UnknownSchemaException" /> otherwise.
        /// </returns>
        /// <exception cref="InvalidSchemaException">
        /// Thrown when a symbols property is not present on the schema.
        /// </exception>
        /// <inheritdoc />
        public virtual JsonSchemaReaderCaseResult Read(JsonElement element, JsonSchemaReaderContext context)
        {
            if (element.ValueKind == JsonValueKind.Object &&
                element.TryGetProperty(JsonAttributeToken.Type, out var type) &&
                type.ValueEquals(JsonSchemaToken.Enum))
            {
                if (!element.TryGetProperty(JsonAttributeToken.Name, out var name) || name.ValueKind != JsonValueKind.String)
                {
                    throw new InvalidSchemaException($"Named schemas must contain a \"{JsonAttributeToken.Name}\" key.");
                }

                if (!element.TryGetProperty(JsonAttributeToken.Symbols, out var symbols) || symbols.ValueKind != JsonValueKind.Array)
                {
                    throw new InvalidSchemaException($"\"{JsonSchemaToken.Enum}\" schemas must contain a \"{JsonAttributeToken.Symbols}\" key.");
                }

                var scope = element.TryGetProperty(JsonAttributeToken.Namespace, out var @namespace)
                    ? @namespace.GetString()
                    : context.Scope;

                var schema = new EnumSchema(QualifyName(name.GetString(), scope))
                {
                    Symbols = symbols.EnumerateArray().Select(symbol => symbol.GetString()).ToArray(),
                };

                if (element.TryGetProperty(JsonAttributeToken.Aliases, out var aliases))
                {
                    schema.Aliases = aliases.EnumerateArray()
                                     .Select(alias => QualifyName(alias.GetString(), scope))
                                     .ToArray();
                }

                if (element.TryGetProperty(JsonAttributeToken.Default, out var @default))
                {
                    schema.Default = @default.GetString();

                    if (!schema.Symbols.Contains(schema.Default))
                    {
                        throw new InvalidSchemaException($"The default value \"{schema.Default}\" is not a symbol in {schema.FullName}.");
                    }
                }

                if (element.TryGetProperty(JsonAttributeToken.Doc, out var doc))
                {
                    schema.Documentation = doc.GetString();
                }

                try
                {
                    context.Schemas.Add(schema.FullName, schema);
                }
                catch (ArgumentException)
                {
                    throw new InvalidSchemaException($"Invalid name; a definition for {schema.FullName} was already read.");
                }

                foreach (var alias in schema.Aliases)
                {
                    if (alias == schema.FullName)
                    {
                        continue;
                    }

                    try
                    {
                        context.Schemas.Add(alias, schema);
                    }
                    catch (ArgumentException)
                    {
                        throw new InvalidSchemaException($"Invalid alias; a definition for {alias} was already read.");
                    }
                }

                return(JsonSchemaReaderCaseResult.FromSchema(schema));
            }
            else
            {
                return(JsonSchemaReaderCaseResult.FromException(new UnknownSchemaException($"{nameof(JsonEnumSchemaReaderCase)} can only be applied to \"{JsonSchemaToken.Enum}\" schemas.")));
            }
        }
 /// <summary>
 /// Reads an enum from the given decoder
 /// </summary>
 /// <param name="reuse">object to store data read</param>
 /// <param name="writerSchema">schema of the object that wrote the data</param>
 /// <param name="readerSchema">schema of the object that will store the data</param>
 /// <param name="dec">decoder object that contains the data to be read</param>
 /// <returns>enum value</returns>
 protected override object ReadEnum(object reuse, EnumSchema writerSchema, Schema readerSchema, Decoder dec)
 {
     return(dec.ReadEnum());
 }
 //enum value should represented as integer
 private void WriteEnum(object source, JsonWriter jsonWriter, EnumSchema enumSchema)
 {
     jsonWriter.WriteValue(source.ToString());
 }
Example #18
0
 /// <summary>
 /// Deserializes a enum. Uses CreateEnum to construct the new enum object.
 /// </summary>
 /// <param name="reuse">If appropirate, uses this instead of creating a new enum object.</param>
 /// <param name="writerSchema">The schema the writer used while writing the enum</param>
 /// <param name="readerSchema">The schema the reader is using</param>
 /// <param name="d">The decoder for deserialization.</param>
 /// <returns>An enum object.</returns>
 protected virtual object ReadEnum(object reuse, EnumSchema writerSchema, Schema readerSchema, Decoder d)
 {
     return(CreateEnum(reuse, readerSchema as EnumSchema, writerSchema[d.ReadEnum()]));
 }
 private JToken EncodeEnum(
     EnumSchema schema,
     GenericEnum value)
 {
     return(new JValue(value.Value));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="EnumTemplate"/> class.
 /// </summary>
 /// <param name="enumSchema">The enum schema.</param>
 /// <param name="userDefinedNamespace">The default namespace.</param>
 /// <param name="forceNamespace">Determines whether the UserDefinedNamespace should be used.</param>
 public EnumTemplate(EnumSchema enumSchema, string userDefinedNamespace, bool forceNamespace)
 {
     this.Schema = enumSchema;
     this.UserDefinedNamespace = userDefinedNamespace;
     this.ForceNamespace       = forceNamespace;
 }
Example #21
0
        protected virtual object ReadEnum(EnumSchema writerSchema, Schema readerSchema, IReader d)
        {
            EnumSchema es = readerSchema as EnumSchema;

            return(new Enum(es, writerSchema[d.ReadEnum()]));
        }
Example #22
0
        public void ThrowWhenSymbolCollectionIsSetToNull()
        {
            var schema = new EnumSchema("test");

            Assert.Throws <ArgumentNullException>(() => schema.Aliases = null);
        }
Example #23
0
 /// <summary>
 /// Serializes an enumeration.
 /// </summary>
 /// <param name="es">The EnumSchema for serialization</param>
 protected abstract WriteItem ResolveEnum(EnumSchema es);
Example #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GenericEnum"/> class.
 /// </summary>
 /// <param name="schema">Schema for this enum.</param>
 /// <param name="value">Value of the enum.</param>
 public GenericEnum(EnumSchema schema, string value)
 {
     Schema = schema;
     Value  = value;
 }
 protected override EnumAccess GetEnumAccess(EnumSchema schema)
 {
     return(new GenericEnumAccess(schema));
 }
Example #26
0
        private ReadItem ResolveEnum(EnumSchema schema)
        {
            var enumAccess = GetEnumAccess(schema);

            return((r, d) => enumAccess.CreateEnum(r, d.ReadEnum()));
        }
Example #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GenericEnum"/> class.
 /// </summary>
 /// <param name="schema">Schema for this enum.</param>
 /// <param name="value">Value of the enum.</param>
 public GenericEnum(EnumSchema schema, string value)
 {
     this.Schema = schema;
     this.Value  = value;
 }
Example #28
0
 protected abstract EnumAccess GetEnumAccess(EnumSchema schema);