github.com/readium/readium-lcp-server@v0.0.0-20240509124024-799e77a0bbd6/rwpm/w3cpublication.go (about)

     1  // Copyright 2020 Readium Foundation. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license
     3  // that can be found in the LICENSE file exposed on Github (readium) in the project repository.
     4  
     5  package rwpm
     6  
     7  import (
     8  	"encoding/json"
     9  )
    10  
    11  // W3CPublication = W3C manifest
    12  type W3CPublication struct {
    13  	Type               string           `json:"type,omitempty"`
    14  	ConformsTo         string           `json:"conformsTo,omitempty"`
    15  	ID                 string           `json:"id,omitempty"`
    16  	URL                string           `json:"url,omitempty"`
    17  	Name               W3CMultiLanguage `json:"name"`
    18  	Publisher          W3CContributors  `json:"publisher,omitempty"`
    19  	Artist             W3CContributors  `json:"artist,omitempty"`
    20  	Author             W3CContributors  `json:"author,omitempty"`
    21  	Colorist           W3CContributors  `json:"colorist,omitempty"`
    22  	Contributor        W3CContributors  `json:"contributor,omitempty"`
    23  	Creator            W3CContributors  `json:"creator,omitempty"`
    24  	Editor             W3CContributors  `json:"editor,omitempty"`
    25  	Illustrator        W3CContributors  `json:"illustrator,omitempty"`
    26  	Inker              W3CContributors  `json:"inker,omitempty"`
    27  	Letterer           W3CContributors  `json:"letterer,omitempty"`
    28  	Penciler           W3CContributors  `json:"penciler,omitempty"`
    29  	ReadBy             W3CContributors  `json:"readBy,omitempty"`
    30  	Translator         W3CContributors  `json:"translator,omitempty"`
    31  	InLanguage         MultiString      `json:"inLanguage,omitempty"`
    32  	DatePublished      *DateOrDatetime  `json:"datePublished,omitempty"`
    33  	DateModified       *DateOrDatetime  `json:"dateModified,omitempty"`
    34  	ReadingProgression string           `json:"readingProgression,omitempty"`
    35  	Duration           string           `json:"duration,omitempty"`
    36  	Description        string           `json:"dcterms:description,omitempty"`
    37  	Subject            Subjects         `json:"dcterms:subject,omitempty"`
    38  	Links              W3CLinks         `json:"links,omitempty"`
    39  	ReadingOrder       W3CLinks         `json:"readingOrder,omitempty"`
    40  	Resources          W3CLinks         `json:"resources,omitempty"`
    41  }
    42  
    43  // W3CLink object
    44  type W3CLink struct {
    45  	URL            string           `json:"url"`
    46  	EncodingFormat string           `json:"encodingFormat,omitempty"`
    47  	Name           W3CMultiLanguage `json:"name,omitempty"`
    48  	Description    W3CMultiLanguage `json:"description,omitempty"`
    49  	Rel            MultiString      `json:"rel,omitempty"`
    50  	Integrity      string           `json:"integrity,omitempty"`
    51  	Duration       string           `json:"duration,omitempty"`
    52  	Alternate      W3CLinks         `json:"alternate,omitempty"`
    53  }
    54  
    55  // W3CContributors is an array of contributors
    56  type W3CContributors []W3CContributor
    57  
    58  // UnmarshalJSON unmarshals contributors
    59  func (c *W3CContributors) UnmarshalJSON(b []byte) error {
    60  
    61  	var ctors []W3CContributor
    62  	ctors = make([]W3CContributor, 1)
    63  	var ctor W3CContributor
    64  
    65  	// literal value
    66  	var literal string
    67  	var err error
    68  	if err = json.Unmarshal(b, &literal); err == nil {
    69  		ctors[0].Name = make([]W3CLocalized, 1)
    70  		ctors[0].Name[0] = W3CLocalized{"und", literal, ""}
    71  
    72  		// object value
    73  	} else if err = json.Unmarshal(b, &ctor); err == nil {
    74  		ctors[0] = ctor
    75  
    76  		// array value
    77  	} else {
    78  		err = json.Unmarshal(b, &ctors)
    79  	}
    80  	if err == nil {
    81  		*c = ctors
    82  		return nil
    83  	}
    84  	return err
    85  }
    86  
    87  // MarshalJSON marshals W3CContributors
    88  func (c W3CContributors) MarshalJSON() ([]byte, error) {
    89  
    90  	// literal value
    91  	if len(c) == 1 && c[0].Name[0].Language == "und" && c[0].Name[0].Value != "" && c[0].ID == "" &&
    92  		c[0].URL == "" && c[0].Identifier == nil {
    93  		return json.Marshal(c[0].Name.Text())
    94  	}
    95  
    96  	// object value
    97  	if len(c) == 1 {
    98  		ctor := c[0]
    99  		return json.Marshal(ctor)
   100  	}
   101  
   102  	// array value
   103  	var ctors []W3CContributor
   104  	ctors = c
   105  	return json.Marshal(ctors)
   106  }
   107  
   108  // W3CContributor construct used internally for all contributors
   109  type W3CContributor struct {
   110  	Type       MultiString      `json:"type,omitempty"`
   111  	Name       W3CMultiLanguage `json:"name,omitempty"`
   112  	ID         string           `json:"id,omitempty"`
   113  	URL        string           `json:"url,omitempty"`
   114  	Identifier MultiString      `json:"identifier,omitempty"`
   115  }
   116  
   117  // UnmarshalJSON unmarshals W3CContributor
   118  func (c *W3CContributor) UnmarshalJSON(b []byte) error {
   119  
   120  	var literal string
   121  	var err error
   122  	if err = json.Unmarshal(b, &literal); err == nil {
   123  		c.Name = make([]W3CLocalized, 1)
   124  		c.Type = nil
   125  		c.Name[0] = W3CLocalized{"und", literal, ""}
   126  		c.ID = ""
   127  		c.URL = ""
   128  		c.Identifier = nil
   129  		return nil
   130  	}
   131  	type Alias W3CContributor
   132  	var ctorAlias Alias
   133  	err = json.Unmarshal(b, &ctorAlias)
   134  	if err != nil {
   135  		return err
   136  	}
   137  	*c = W3CContributor(ctorAlias)
   138  	return nil
   139  }
   140  
   141  // MarshalJSON marshals W3CContributor
   142  func (c W3CContributor) MarshalJSON() ([]byte, error) {
   143  
   144  	// literal value
   145  	if c.Name[0].Language == "und" && c.Name[0].Value != "" && c.ID == "" && c.URL == "" && c.Identifier == nil {
   146  		return json.Marshal(c.Name[0].Value)
   147  	}
   148  	type Alias W3CContributor
   149  	ctorAlias := Alias{c.Type, c.Name, c.ID, c.URL, c.Identifier}
   150  	return json.Marshal(ctorAlias)
   151  }
   152  
   153  // W3CMultiLanguage struct
   154  type W3CMultiLanguage []W3CLocalized
   155  
   156  // W3CLocalized represents a single value of a W3CMultiLanguage property
   157  type W3CLocalized struct {
   158  	Language  string `json:"language"`
   159  	Value     string `json:"value"`
   160  	Direction string `json:"direction,omitempty"`
   161  }
   162  
   163  // UnmarshalJSON unmarshalls W3CMultilanguge
   164  func (m *W3CMultiLanguage) UnmarshalJSON(b []byte) error {
   165  
   166  	var locs []W3CLocalized
   167  	locs = make([]W3CLocalized, 1)
   168  	var loc W3CLocalized
   169  	var literal string
   170  	var err error
   171  
   172  	// literal value
   173  	if err = json.Unmarshal(b, &literal); err == nil {
   174  		locs[0] = W3CLocalized{"und", literal, ""}
   175  
   176  		// object value
   177  	} else if err = json.Unmarshal(b, &loc); err == nil {
   178  		locs[0] = loc
   179  
   180  		// array value
   181  	} else {
   182  		err = json.Unmarshal(b, &locs)
   183  	}
   184  	if err == nil {
   185  		*m = locs
   186  		return nil
   187  	}
   188  	return err
   189  }
   190  
   191  // MarshalJSON marshalls W3CMultiLanguage
   192  func (m W3CMultiLanguage) MarshalJSON() ([]byte, error) {
   193  
   194  	// literal value
   195  	if len(m) == 1 && m[0].Language == "und" &&
   196  		m[0].Value != "" && m[0].Direction == "" {
   197  		return json.Marshal(m[0].Value)
   198  	}
   199  
   200  	// object value
   201  	if len(m) == 1 {
   202  		loc := m[0]
   203  		return json.Marshal(loc)
   204  	}
   205  
   206  	// array value
   207  	locs := []W3CLocalized(m)
   208  	return json.Marshal(locs)
   209  }
   210  
   211  // Text returns the "und" language value or the first value found in the map
   212  func (m W3CMultiLanguage) Text() string {
   213  
   214  	for _, ml := range m {
   215  		if ml.Language == "und" {
   216  			return ml.Value
   217  		}
   218  	}
   219  	return m[0].Value
   220  }
   221  
   222  // UnmarshalJSON unmarshalls W3CLocalized
   223  func (l *W3CLocalized) UnmarshalJSON(b []byte) error {
   224  
   225  	var literal string
   226  	var err error
   227  
   228  	// literal value
   229  	if err = json.Unmarshal(b, &literal); err == nil {
   230  		*l = W3CLocalized{"und", literal, ""}
   231  		return nil
   232  
   233  	}
   234  	// object value
   235  	type Alias W3CLocalized
   236  	var locAlias Alias
   237  	err = json.Unmarshal(b, &locAlias)
   238  	if err != nil {
   239  		return err
   240  	}
   241  	*l = W3CLocalized(locAlias)
   242  	return nil
   243  
   244  }
   245  
   246  // MarshalJSON marshalls W3CLocalized
   247  func (l W3CLocalized) MarshalJSON() ([]byte, error) {
   248  
   249  	// literal value
   250  	if l.Language == "und" && l.Value != "" && l.Direction == "" {
   251  		return json.Marshal(l.Value)
   252  	}
   253  	// object value
   254  	type Alias W3CLocalized
   255  	locAlias := Alias{l.Language, l.Value, l.Direction}
   256  	return json.Marshal(locAlias)
   257  }
   258  
   259  // W3CLinks struct
   260  type W3CLinks []W3CLink
   261  
   262  // UnmarshalJSON unmarshalls W3CLinks
   263  func (l *W3CLinks) UnmarshalJSON(b []byte) error {
   264  
   265  	var lnks []W3CLink
   266  	lnks = make([]W3CLink, 1)
   267  	var lnk W3CLink
   268  
   269  	// literal value
   270  	var literal string
   271  	var err error
   272  	if err = json.Unmarshal(b, &literal); err == nil {
   273  		lnks[0].URL = literal
   274  
   275  		// object value
   276  	} else if err = json.Unmarshal(b, &lnk); err == nil {
   277  		lnks[0] = lnk
   278  
   279  		// array value
   280  	} else {
   281  		err = json.Unmarshal(b, &lnks)
   282  	}
   283  	if err == nil {
   284  		*l = lnks
   285  		return nil
   286  	}
   287  	return err
   288  }
   289  
   290  // MarshalJSON marshals W3CLinks
   291  func (l W3CLinks) MarshalJSON() ([]byte, error) {
   292  
   293  	// literal value
   294  	if len(l) == 1 && l[0].URL != "" &&
   295  		l[0].EncodingFormat == "" && l[0].Name == nil && l[0].Description == nil &&
   296  		l[0].Rel == nil && l[0].Integrity == "" && l[0].Duration == "" && l[0].Alternate == nil {
   297  		return json.Marshal(l[0].URL)
   298  	}
   299  
   300  	// object value
   301  	if len(l) == 1 {
   302  		lnk := l[0]
   303  		return json.Marshal(lnk)
   304  	}
   305  
   306  	// array value
   307  	var lnks []W3CLink
   308  	lnks = l
   309  	return json.Marshal(lnks)
   310  }
   311  
   312  // UnmarshalJSON unmarshals W3CLink
   313  func (l *W3CLink) UnmarshalJSON(b []byte) error {
   314  
   315  	var literal string
   316  	var err error
   317  
   318  	// literal value
   319  	if err = json.Unmarshal(b, &literal); err == nil {
   320  		*l = W3CLink{URL: literal}
   321  		return nil
   322  	}
   323  	// object vcalue
   324  	type Alias W3CLink
   325  	var lnkAlias Alias
   326  	err = json.Unmarshal(b, &lnkAlias)
   327  	if err != nil {
   328  		return err
   329  	}
   330  	*l = W3CLink(lnkAlias)
   331  	return nil
   332  }
   333  
   334  // MarshalJSON marshals W3CLink
   335  func (l W3CLink) MarshalJSON() ([]byte, error) {
   336  
   337  	// literal value
   338  	if l.URL != "" && l.EncodingFormat == "" && l.Name == nil && l.Description == nil &&
   339  		l.Rel == nil && l.Integrity == "" && l.Duration == "" && l.Alternate == nil {
   340  		return json.Marshal(l.URL)
   341  	}
   342  	type Alias W3CLink
   343  	lnkAlias := Alias{l.URL, l.EncodingFormat, l.Name, l.Description, l.Rel, l.Integrity, l.Duration, l.Alternate}
   344  	return json.Marshal(lnkAlias)
   345  }