create.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package kinds
  2. // TODO: rename this to `construct`
  3. // TODO: I think this should be moved to
  4. // package request, then Fetch will return an Object
  5. // directly by calling Create, and Create will
  6. // still work fine
  7. import (
  8. "errors"
  9. "net/url"
  10. "mimicry/shared"
  11. "mimicry/request"
  12. )
  13. type Object interface {
  14. String() string
  15. Kind() (string, error)
  16. Identifier() (*url.URL, error)
  17. Category() string
  18. }
  19. // TODO, add a verbose debugging output mode
  20. // to debug problems that arise with this thing
  21. // looping too much and whatnot
  22. // source is where it came from, if source is different
  23. // from the element's id, it will be refetched
  24. // maybe change back to taking in a unstructured shared.JSON
  25. func Create(input any, source *url.URL) (Object, error) {
  26. unstructured, ok := input.(shared.JSON)
  27. if !ok {
  28. return nil, errors.New("Cannot construct with a non-object JSON")
  29. }
  30. kind, err := shared.Get[string](unstructured, "type")
  31. if err != nil {
  32. return nil, err
  33. }
  34. id, err := shared.GetURL(unstructured, "id")
  35. if err != nil {
  36. return nil, err
  37. }
  38. // if the JSON came from a source (e.g. inline in another collection), with a
  39. // different hostname than its ID, refetch
  40. // if the JSON only has two keys (type and id), refetch
  41. if source != nil && source.Hostname() != id.Hostname() || len(unstructured) <= 2 {
  42. response, err := request.Fetch(id)
  43. if err != nil {
  44. return nil, err
  45. }
  46. return Create(response, nil)
  47. }
  48. // TODO: if the only keys are id and type,
  49. // you need to do a fetch to get the other keys
  50. switch kind {
  51. case "Article":
  52. fallthrough
  53. case "Audio":
  54. fallthrough
  55. case "Document":
  56. fallthrough
  57. case "Image":
  58. fallthrough
  59. case "Note":
  60. fallthrough
  61. case "Page":
  62. fallthrough
  63. case "Video":
  64. // TODO: figure out the way to do this directly
  65. post := Post{}
  66. post = unstructured
  67. return post, nil
  68. // case "Create":
  69. // fallthrough
  70. // case "Announce":
  71. // fallthrough
  72. // case "Dislike":
  73. // fallthrough
  74. // case "Like":
  75. // fallthrough
  76. // case "Question":
  77. // return Activity{unstructured}, nil
  78. case "Application":
  79. fallthrough
  80. case "Group":
  81. fallthrough
  82. case "Organization":
  83. fallthrough
  84. case "Person":
  85. fallthrough
  86. case "Service":
  87. // TODO: nicer way to do this?
  88. actor := Actor{}
  89. actor = unstructured
  90. return actor, nil
  91. // case "Link":
  92. // return Link{unstructured}, nil
  93. // case "Collection":
  94. // fallthrough
  95. // case "OrderedCollection":
  96. // return Collection{unstructured}, nil
  97. // case "CollectionPage":
  98. // fallthrough
  99. // case "OrderedCollectionPage":
  100. // return CollectionPage{unstructured}, nil
  101. default:
  102. return nil, errors.New("Object of Type " + kind + " unsupported")
  103. }
  104. }