Просмотр исходного кода

Implemented flow support for struct fields.

Gustavo Niemeyer 15 лет назад
Родитель
Сommit
f0766b44ca
3 измененных файлов с 49 добавлено и 33 удалено
  1. 39 33
      encode.go
  2. 7 0
      encode_test.go
  3. 3 0
      goyaml.go

+ 39 - 33
encode.go

@@ -16,6 +16,7 @@ type encoder struct {
     out []byte
     tmp []byte
     tmph *reflect.SliceHeader
+    flow bool
 }
 
 
@@ -126,28 +127,33 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
 }
 
 func (e *encoder) mapv(tag string, in *reflect.MapValue) {
-    var ctag *C.yaml_char_t
-    var free func()
-    var cimplicit C.int
-    if tag != "" {
-        ctag, free = ystr(tag)
-        defer free()
-        cimplicit = 0
-    } else {
-        cimplicit = 1
-    }
-    C.yaml_mapping_start_event_initialize(&e.event, nil, ctag, cimplicit,
-                                          C.YAML_BLOCK_MAPPING_STYLE)
-    e.emit()
-    for _, k := range in.Keys() {
-        e.marshal("", k)
-        e.marshal("", in.Elem(k))
-    }
-    C.yaml_mapping_end_event_initialize(&e.event)
-    e.emit()
+    e.mappingv(tag, func() {
+        for _, k := range in.Keys() {
+            e.marshal("", k)
+            e.marshal("", in.Elem(k))
+        }
+    })
 }
 
 func (e *encoder) structv(tag string, in *reflect.StructValue) {
+    fields, err := getStructFields(in.Type().(*reflect.StructType))
+    if err != nil {
+        panic(err)
+    }
+    e.mappingv(tag, func() {
+        for i, info := range fields.List {
+            value := in.Field(i)
+            if info.Conditional && isZero(value) {
+                continue
+            }
+            e.marshal("", reflect.NewValue(info.Key))
+            e.flow = info.Flow
+            e.marshal("", value)
+        }
+    })
+}
+
+func (e *encoder) mappingv(tag string, f func()) {
     var ctag *C.yaml_char_t
     var free func()
     cimplicit := C.int(1)
@@ -156,21 +162,15 @@ func (e *encoder) structv(tag string, in *reflect.StructValue) {
         defer free()
         cimplicit = 0
     }
+    cstyle := C.yaml_mapping_style_t(C.YAML_BLOCK_MAPPING_STYLE)
+    if e.flow {
+        e.flow = false
+        cstyle = C.YAML_FLOW_MAPPING_STYLE
+    }
     C.yaml_mapping_start_event_initialize(&e.event, nil, ctag, cimplicit,
-                                          C.YAML_BLOCK_MAPPING_STYLE)
+                                          cstyle)
     e.emit()
-    fields, err := getStructFields(in.Type().(*reflect.StructType))
-    if err != nil {
-        panic(err)
-    }
-    for i, info := range fields.List {
-        value := in.Field(i)
-        if info.Conditional && isZero(value) {
-            continue
-        }
-        e.marshal("", reflect.NewValue(info.Key))
-        e.marshal("", value)
-    }
+    f()
     C.yaml_mapping_end_event_initialize(&e.event)
     e.emit()
 }
@@ -186,8 +186,14 @@ func (e *encoder) slicev(tag string, in *reflect.SliceValue) {
     } else {
         cimplicit = 1
     }
+
+    cstyle := C.yaml_sequence_style_t(C.YAML_BLOCK_SEQUENCE_STYLE)
+    if e.flow {
+        e.flow = false
+        cstyle = C.YAML_FLOW_SEQUENCE_STYLE
+    }
     C.yaml_sequence_start_event_initialize(&e.event, nil, ctag, cimplicit,
-                                           C.YAML_BLOCK_SEQUENCE_STYLE)
+                                           cstyle)
     e.emit()
     n := in.Len()
     for i := 0; i < n; i++ {

+ 7 - 0
encode_test.go

@@ -54,6 +54,13 @@ var marshalTests = []struct{data string; value interface{}}{
     // Conditional flag
     {"a: 1\n", &struct{A int "a/c"; B int "b/c"}{1, 0}},
     {"{}\n", &struct{A int "a/c"; B int "b/c"}{0, 0}},
+
+    // Flow flag
+    {"a: [1, 2]\n", &struct{A []int "a/f"}{[]int{1, 2}}},
+    {"a: {b: c}\n",
+     &struct{A map[string]string "a/f"}{map[string]string{"b": "c"}}},
+    {"a: {b: c}\n",
+     &struct{A struct{B string} "a/f"}{struct{B string}{"c"}}},
 }
 
 

+ 3 - 0
goyaml.go

@@ -63,6 +63,7 @@ type fieldInfo struct {
     Key string
     Num int
     Conditional bool
+    Flow bool
 }
 
 var fieldMap = make(map[string]*structFields)
@@ -96,6 +97,8 @@ func getStructFields(st *reflect.StructType) (*structFields, os.Error) {
                 switch c {
                 case int('c'):
                     info.Conditional = true
+                case int('f'):
+                    info.Flow = true
                 default:
                     panic("Unsupported field flag: " + string([]int{c}))
                 }