using Raven.Client.Documents; namespace zero.Search; public class SearchIndexMap { internal Type Type; internal string _Icon; protected string _group; protected string[] _fields; protected Func _modify; const string mapTemplate = @"map('{collection}', function (x) { return { Id: x.Id, Group: '{group}', Name: x.Name, IsActive: x.IsActive, Fields: [{fields}] }; });"; internal SearchIndexMap(Type type, string icon = null) { Type = type; _group = "__TODO"; _Icon = icon; } internal string BuildInstruction(IDocumentStore store) { return TokenReplacement.Apply(mapTemplate, new() { { "collection", store.Conventions.GetCollectionName(Type) }, { "group", _group }, { "fields", BuildFieldArray(_fields) } }); } internal string BuildFieldArray(string[] fields) { if (fields == null || !fields.Any()) { return String.Empty; } return "x." + String.Join(", x.", fields); } internal bool CanModify(Type type) { return Type.IsAssignableFrom(type); } internal async Task Modify(ZeroEntity entity, SearchResult result, IZeroOptions options) { if (_modify != null) { await _modify(entity, result, options); } } } public class SearchIndexMap : SearchIndexMap where T : ZeroEntity { internal SearchIndexMap(string icon = null) : base(typeof(T), icon) { } public virtual SearchIndexMap Icon(string icon) { _Icon = icon; return this; } public SearchIndexMap Display(Action modify = null) { _modify = (x, res, opts) => { modify?.Invoke(x as T, res); return Task.CompletedTask; }; return this; } public SearchIndexMap Display(Func modify = null) { _modify = (x, res, opts) => modify?.Invoke(x as T, res); return this; } public SearchIndexMap Display(Action modify = null) { _modify = (x, res, opts) => { modify?.Invoke(x as T, res, opts); return Task.CompletedTask; }; return this; } public SearchIndexMap Display(Func modify = null) { _modify = (x, res, opts) => modify?.Invoke(x as T, res, opts); return this; } public SearchIndexMap Fields(params string[] fieldNames) { _fields = fieldNames; return this; } }