unioffice/creator.go
Vyacheslav Zgordan dd7713e1e3 Functions2 (#348)
* MATCH, IFS, MAXA, MINA
* OFFSET fixed
* ISBLANK, ISERR, ISERROR, ISEVEN ,ISFORMULA, ISNONTEXT, ISNUMBER, ISODD, ISTEXT
* ISLEAPYEAR, ISLOGICAL, ISNA, ISREF
* FIND, FINDB
* SEARCH, SEARCHB
* CONCAT, CONCATENATE
* YEAR, YEARFRAC
* CONCAT is fixed, now TRUE and FALSE are concatenated instead of 1 and 0 in case of boolean results
* NOW, TODAY, TIME, TIMEVALUE
* DATE
* DATEDIF
2019-11-20 23:21:00 +00:00

51 lines
1.5 KiB
Go

// Copyright 2017 FoxyUtils ehf. All rights reserved.
//
// Use of this source code is governed by the terms of the Affero GNU General
// Public License version 3.0 as published by the Free Software Foundation and
// appearing in the file LICENSE included in the packaging of this file. A
// commercial license can be purchased on https://unidoc.io.
package unioffice
import (
"encoding/xml"
"errors"
"fmt"
"reflect"
)
// Any is the interface used for marshaling/unmarshaling xsd:any
type Any interface {
MarshalXML(e *xml.Encoder, start xml.StartElement) error
UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
}
var creatorFns = map[string]interface{}{}
// RegisterConstructor registers a constructor function used for unmarshaling
// xsd:any elements.
func RegisterConstructor(ns, name string, fn interface{}) {
creatorFns[ns+"/"+name] = fn
}
// CreateElement creates an element with the given namespace and name. It is
// used to unmarshal some xsd:any elements to the appropriate concrete type.
func CreateElement(start xml.StartElement) (Any, error) {
fn, ok := creatorFns[start.Name.Space+"/"+start.Name.Local]
if !ok {
r := &XSDAny{}
return r, nil
}
v := reflect.ValueOf(fn)
res := v.Call(nil)
if len(res) != 1 {
return nil, fmt.Errorf("constructor function should return one value, got %d", len(res))
}
any, ok := res[0].Interface().(Any)
if !ok {
return nil, errors.New("constructor function should return any 'Any'")
}
return any, nil
}