using Google.Protobuf.WellKnownTypes; namespace DynamicCrud.Tests.Grpc; /// /// Utilidades para desempacar el campo data de , /// que llega como un nativo de protobuf: un array de objetos en GetAll/Search, /// o un objeto suelto en GetById. /// internal static class CrudData { /// Interpreta la respuesta como lista de registros. Un objeto suelto cuenta como lista de uno. internal static List> AsRecords(Value? data) { if (data is null) return new(); return data.KindCase switch { Value.KindOneofCase.ListValue => data.ListValue.Values .Where(v => v.KindCase == Value.KindOneofCase.StructValue) .Select(v => (IDictionary)v.StructValue.Fields) .ToList(), Value.KindOneofCase.StructValue => new() { data.StructValue.Fields }, _ => new(), }; } /// Interpreta la respuesta como un registro único (GetById). internal static IDictionary? AsRecord(Value? data) => data?.KindCase == Value.KindOneofCase.StructValue ? data.StructValue.Fields : null; /// /// Representación en texto de un valor, para comparar sin pelearse con el tipo. /// Devuelve null cuando el valor es nulo en la base. /// internal static string? Scalar(Value v) => v.KindCase switch { Value.KindOneofCase.StringValue => v.StringValue, Value.KindOneofCase.NumberValue => v.NumberValue.ToString("0.####################"), Value.KindOneofCase.BoolValue => v.BoolValue ? "true" : "false", Value.KindOneofCase.NullValue => null, _ => null, }; /// Valor escalar de un campo del registro, o null si no existe o es nulo. internal static string? Field(IDictionary record, string name) => record.TryGetValue(name, out var v) ? Scalar(v) : null; }