From 58e73a0d974c9b95a6ff8ff3d47b1f25c4cfb033 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Mon, 8 Nov 2021 16:16:29 +0800 Subject: [PATCH] feat: Generate enable feature pairs (#998) Signed-off-by: Xuanwo --- definitions/gen_pair.go | 13 ++++++++++- definitions/gen_service.go | 33 +++++++++++++++++++++++++-- definitions/metadata.go | 14 ++++++++++++ definitions/namespace.go | 23 +++++++++++++++++++ definitions/pairs.go | 13 +++++++++++ definitions/tests/generated_test.go | 8 +++++++ pairs/generated.go | 35 +++++++++++++++++++++++++++++ 7 files changed, 136 insertions(+), 3 deletions(-) diff --git a/definitions/gen_pair.go b/definitions/gen_pair.go index 13784e176..59c35011c 100644 --- a/definitions/gen_pair.go +++ b/definitions/gen_pair.go @@ -23,8 +23,19 @@ func GeneratePair(path string) { %s %s`, pname, v.Name, pname, v.Description) xfn := f.NewFunction("With" + pname) - xfn.AddParameter("v", v.Type.FullName("pairs")) xfn.AddResult("p", "types.Pair") + + // If value type is bool, we don't need to accept parameters. + if v.Type.Name == "bool" { + xfn.AddBody( + gg.Return( + gg.Value("types.Pair"). + AddField("Key", gg.Lit(v.Name)). + AddField("Value", "true"))) + continue + } + + xfn.AddParameter("v", v.Type.FullName("pairs")) xfn.AddBody( gg.Return( gg.Value("types.Pair"). diff --git a/definitions/gen_service.go b/definitions/gen_service.go index f631d5ff6..543604134 100644 --- a/definitions/gen_service.go +++ b/definitions/gen_service.go @@ -419,8 +419,7 @@ func (gs *genService) generateFactory() { newStorager := f.NewFunction("NewStorager"). WithReceiver("f", "*Factory"). AddResult("sto", "types.Storager"). - AddResult("err", "error"). - AddBody() + AddResult("err", "error") if gs.data.Storage == nil { newStorager.AddBody(`return nil, errors.New("storager not implemented")`) } else if !gs.implemented[NamespaceFactory]["new_storage"] { @@ -433,6 +432,36 @@ func (gs *genService) generateFactory() { } else { newStorager.AddBody("return f.newStorage()") } + + serviceFeatures := f.NewFunction("serviceFeatures"). + WithReceiver("f", "*Factory"). + AddResult("s", "types.ServiceFeatures") + for _, op := range gs.data.Service.Operations() { + if gs.data.Service.HasFeature(op.Name) { + serviceFeatures.AddBody(gg.S("s.%s = true", templateutils.ToPascal(op.Name))) + } + } + for _, fe := range gs.data.Service.VirtualFeatures() { + serviceFeatures.AddBody( + gg.If("f." + templateutils.ToPascal("enable_"+fe.Name)).AddBody( + gg.S("s.%s = true", templateutils.ToPascal(fe.Name)))) + } + serviceFeatures.AddBody(gg.Return()) + + storageFeatures := f.NewFunction("storageFeatures"). + WithReceiver("f", "*Factory"). + AddResult("s", "types.StorageFeatures") + for _, op := range gs.data.Storage.Operations() { + if gs.data.Storage.HasFeature(op.Name) { + storageFeatures.AddBody(gg.S("s.%s = true", templateutils.ToPascal(op.Name))) + } + } + for _, fe := range gs.data.Storage.VirtualFeatures() { + storageFeatures.AddBody( + gg.If("f." + templateutils.ToPascal("enable_"+fe.Name)).AddBody( + gg.S("s.%s = true", templateutils.ToPascal(fe.Name)))) + } + storageFeatures.AddBody(gg.Return()) } func (gs *genService) generateFunctionPairs(ns Namespace, op Operation) { diff --git a/definitions/metadata.go b/definitions/metadata.go index ec9427d5d..15d76d4d7 100644 --- a/definitions/metadata.go +++ b/definitions/metadata.go @@ -13,6 +13,7 @@ type Metadata struct { func (m Metadata) Normalize() Metadata { m.buildDefaultPairs() + m.buildFeaturePairs() return m } @@ -31,3 +32,16 @@ func (m *Metadata) buildDefaultPairs() { m.Pairs = append(m.Pairs, dp...) m.Factory = append(m.Factory, dp...) } + +func (m *Metadata) buildFeaturePairs() { + dp := make(map[string]bool) + for _, v := range []Namespace{m.Service, m.Storage} { + for _, f := range v.VirtualFeatures() { + dp["enable_"+f.Name] = true + } + } + + for name := range dp { + m.Factory = append(m.Factory, PairMap[name]) + } +} diff --git a/definitions/namespace.go b/definitions/namespace.go index 198265018..898589894 100644 --- a/definitions/namespace.go +++ b/definitions/namespace.go @@ -4,6 +4,7 @@ type Namespace interface { Name() string Operations() []Operation HasFeature(name string) bool + VirtualFeatures() []Feature ListPairs(name string) []Pair } @@ -19,6 +20,17 @@ func (s Service) HasFeature(name string) bool { return s.Features.Has(name) } +func (s Service) VirtualFeatures() []Feature { + fs := make([]Feature, 0) + + for _, f := range FeaturesArray { + if f.HasNamespace(NamespaceService) && s.Features.Has(f.Name) { + fs = append(fs, f) + } + } + return SortFeatures(fs) +} + func (s Storage) Name() string { return NamespaceStorage } @@ -30,3 +42,14 @@ func (s Storage) Operations() []Operation { func (s Storage) HasFeature(name string) bool { return s.Features.Has(name) } + +func (s Storage) VirtualFeatures() []Feature { + fs := make([]Feature, 0) + + for _, f := range FeaturesArray { + if f.HasNamespace(NamespaceStorage) && s.Features.Has(f.Name) { + fs = append(fs, f) + } + } + return SortFeatures(fs) +} diff --git a/definitions/pairs.go b/definitions/pairs.go index 501ffca28..99ca62a66 100644 --- a/definitions/pairs.go +++ b/definitions/pairs.go @@ -52,6 +52,19 @@ func init() { } PairArray = append(PairArray, dps...) + // Build feature pairs. + fps := make([]Pair, 0) + for _, f := range FeaturesArray { + fps = append(fps, Pair{ + Name: "enable_" + f.Name, + Type: Type{Name: "bool"}, + Description: "Enable feature " + f.Name, + global: true, + }) + } + PairArray = append(PairArray, fps...) + + // Setup maps. for _, v := range PairArray { PairMap[v.Name] = v } diff --git a/definitions/tests/generated_test.go b/definitions/tests/generated_test.go index b12188b85..040e90da3 100644 --- a/definitions/tests/generated_test.go +++ b/definitions/tests/generated_test.go @@ -203,6 +203,14 @@ func (f *Factory) NewServicer() (srv types.Servicer, err error) { func (f *Factory) NewStorager() (sto types.Storager, err error) { return f.newStorage() } +func (f *Factory) serviceFeatures() (s types.ServiceFeatures) { + s.Delete = true + return +} +func (f *Factory) storageFeatures() (s types.StorageFeatures) { + s.Read = true + return +} var _ types.Servicer = &Service{} diff --git a/pairs/generated.go b/pairs/generated.go index 9ab6246c0..ab5e28498 100644 --- a/pairs/generated.go +++ b/pairs/generated.go @@ -52,6 +52,41 @@ func WithDefaultIoCallback(v func([]byte)) (p types.Pair) { return types.Pair{Key: "default_io_callback", Value: v} } +// WithEnableLoosePair will apply enable_loose_pair value to Options. +// +// EnableLoosePair Enable feature loose_pair +func WithEnableLoosePair() (p types.Pair) { + return types.Pair{Key: "enable_loose_pair", Value: true} +} + +// WithEnableVirtualDir will apply enable_virtual_dir value to Options. +// +// EnableVirtualDir Enable feature virtual_dir +func WithEnableVirtualDir() (p types.Pair) { + return types.Pair{Key: "enable_virtual_dir", Value: true} +} + +// WithEnableVirtualLink will apply enable_virtual_link value to Options. +// +// EnableVirtualLink Enable feature virtual_link +func WithEnableVirtualLink() (p types.Pair) { + return types.Pair{Key: "enable_virtual_link", Value: true} +} + +// WithEnableVirtualObjectMetadata will apply enable_virtual_object_metadata value to Options. +// +// EnableVirtualObjectMetadata Enable feature virtual_object_metadata +func WithEnableVirtualObjectMetadata() (p types.Pair) { + return types.Pair{Key: "enable_virtual_object_metadata", Value: true} +} + +// WithEnableWriteEmptyObject will apply enable_write_empty_object value to Options. +// +// EnableWriteEmptyObject Enable feature write_empty_object +func WithEnableWriteEmptyObject() (p types.Pair) { + return types.Pair{Key: "enable_write_empty_object", Value: true} +} + // WithEndpoint will apply endpoint value to Options. // // Endpoint specify how to provide endpoint for service or storage