1"use strict";(globalThis.webpackChunkconvex_docs=globalThis.webpackChunkconvex_docs||[]).push([[698],{7028:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>i});var t=a(758);const r={},s=t.createContext(r);function d(e){const n=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),t.createElement(s.Provider,{value:n},e.children)}},7848:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"cad/metadata/index","title":"CAD013: Metadata","description":"Overview","source":"@site/docs/cad/013_metadata/index.md","sourceDirName":"cad/013_metadata","slug":"/cad/metadata/","permalink":"/docs/cad/metadata/","draft":false,"unlisted":false,"editUrl":"https://github.com/Convex-Dev/design/tree/develop/docs/cad/013_metadata/index.md","tags":[],"version":"current","frontMatter":{},"sidebar":"cadsSidebar","previous":{"title":"CAD012: Numerics","permalink":"/docs/cad/numerics/"},"next":{"title":"CAD014: Convex Name System","permalink":"/docs/cad/cns/"}}');var r=a(6070),s=a(7028);const d={},i="CAD013: Metadata",o={},c=[{value:"Overview",id:"overview",level:2},{value:"Usage",id:"usage",level:2},{value:"Declaring metadata",id:"declaring-metadata",level:3},{value:"Retrieving metadata",id:"retrieving-metadata",level:3},{value:"Standard structures",id:"standard-structures",level:2},{value:"Documentation",id:"documentation",level:3},{value:"<code>:description</code>",id:"description",level:4},{value:"<code>:errors</code>",id:"errors",level:4},{value:"<code>:examples</code>",id:"examples",level:4},{value:"<code>:signature</code>",id:"signature",level:4},{value:"<code>:type</code>",id:"type",level:4},{value:"Expanders",id:"expanders",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"cad013-metadata",children:"CAD013: Metadata"})}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(n.p,{children:"The CVM provides a powerful facility for attaching a metadata map to a defined symbol. The purpose of metadata is to provide any information on a defined symbol independent of the value this symbol holds."}),"\n",(0,r.jsx)(n.p,{children:"Some metadata information, if specified, MUST follow a particular structure for external purposes. For instance, this CAD describes how to document a symbol by following an expected structure."}),"\n",(0,r.jsx)(n.p,{children:"Other information in metadata CAN follow any arbitrary structure. Creators of such SHOULD collaborate with the community to establish useful standards where appropriate (which may include updates to this CAD)"}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(n.h3,{id:"declaring-metadata",children:"Declaring metadata"}),"\n",(0,r.jsxs)(n.p,{children:["Metadata is a map containing any arbitrary set of key-values. It is specified after the defined symbol, prefixed with ",(0,r.jsx)(n.code,{children:"^"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-clojure",children:'(def some-symbol\n ^{:my ["meta" :data]}\n 42)\n'})}),"\n",(0,r.jsx)(n.h3,{id:"retrieving-metadata",children:"Retrieving metadata"}),"\n",(0,r.jsx)(n.p,{children:"The core library defines a function for retrieving metadata:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-clojure",children:'(lookup-meta \'some-symbol)\n\n;; Following previous example, returns `{:my ["meta" :data]}`\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Each account stores a map of ",(0,r.jsx)(n.code,{children:"symbol"})," to ",(0,r.jsx)(n.code,{children:"metadata map"})," under ",(0,r.jsx)(n.code,{children:":metadata"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-clojure",children:'(get (account *address*)\n :metadata)\n\n;; Following previous examples, returns `{\'some-symbol {:my ["meta" :data]}}`\n'})}
1),"\n",(0,r.jsx)(n.h2,{id:"standard-structures",children:"Standard structures"}),"\n",(0,r.jsx)(n.p,{children:"For some purposes, metadata must follow at least a set of contraints so that the CVM or any external consumer has access to relevant information."}),"\n",(0,r.jsx)(n.h3,{id:"documentation",children:"Documentation"}),"\n",(0,r.jsx)(n.p,{children:"Attaching documentation to a symbol allows any user to gain insight about the purpose of that symbol. Notably, it can provide information regarding how a function is\nintended to be used and why."}),"\n",(0,r.jsx)(n.p,{children:"User MAY specify any information as described below. None is mandatory. When specified, structure MUST conform as expected by any external consumer."}),"\n",(0,r.jsxs)(n.p,{children:["A documentation map MAY be attached to metadata under ",(0,r.jsx)(n.code,{children:":doc"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Reference example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-clojure",children:'(defn add\n\n ^{:doc {:description "Adds 2 numbers together."\n :errors {:CAST "If an argument cannot be cast to a number"}\n :examples [{:code "(add 2 3)"}]\n :signature [{:params [a b]\n :returns Number}]\n :type :function}}\n\n :implementation...)\n'})}),"\n",(0,r.jsx)(n.p,{children:"Documentation map MAY contain any of the key-values described in the following subsections."}),"\n",(0,r.jsx)(n.h4,{id:"description",children:(0,r.jsx)(n.code,{children:":description"})}),"\n",(0,r.jsx)(n.p,{children:"String describing the symbol in human language ."}),"\n",(0,r.jsx)(n.p,{children:"TODO. Also a vector of strings where each string is a paragraph for easier formatting?"}),"\n",(0,r.jsx)(n.h4,{id:"errors",children:(0,r.jsx)(n.code,{children:":errors"})}),"\n",(0,r.jsxs)(n.p,{children:["Assuming the symbol is callable, map of ",(0,r.jsx)(n.code,{children:"error code"})," to ",(0,r.jsx)(n.code,{children:"string"})," describing in human language how and why calling this function might fail."]}),"\n",(0,r.jsxs)(n.p,{children:["See also ",(0,r.jsx)(n.a,{href:"/docs/cad/errors/",children:"CAD 011"})," about errors."]}),"\n",(0,r.jsx)(n.h4,{id:"examples",children:(0,r.jsx)(n.code,{children:":examples"})}),"\n",(0,r.jsx)(n.p,{children:"Assuming the symbol is callable, vector of examples where an example is a map which MAY contain:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Key"}),(0,r.jsx)(n.th,{children:"Value"})]})}),(0,r.jsx)(n.tbody,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:":code"})}),(0,r.jsx)(n.td,{children:"String, excerpt of code demonstrating a function call"})]})})]}),"\n",(0,r.jsxs)(n.p,{children:["TODO. Should it be a string? Is it for memory issues?\nTODO. Should it also have a ",(0,r.jsx)(n.code,{children:":return"})," key-value?"]}),"\n",(0,r.jsx)(n.h4,{id:"signature",children:(0,r.jsx)(n.code,{children:":signature"})}),"\n",(0,r.jsx)(n.p,{children:"Assuming the symbol is callable, vector of signatures where a signature is a map which MAY contain:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Key"}),(0,r.jsx)(n.th,{children:"Value"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:":params"})}),(0,r.jsx)(n.td,{children:"Vector of parameters"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:":returns"})}),(0,r.jsx)(n.td,{children:"Type of returned value"})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["TODO. Is there a list of supported types for ",(0,r.jsx)(n.code,{children:":returns"}),"? More future-proof to have a human-readable string?"]}),"\n",(0,r.jsx)(n.h4,{id:"type",children:(0,r.jsx)(n.code,{children:":type"})}),"\n",(0,r.jsx)(n.p,{children:"Keyword designating what category the symbol belongs to:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Keyword"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:":function"})}),(0,r.jsx)(n.td,{children:"Symbol is a regular function"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:":macro"})}),(0,r.jsx)(n.td,{children:"Symbol is a macro"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"TODO. What about other values?"}),"\n",(0,r.jsx)(n.h3,{id:"expanders",children:"Expanders"}
1),"\n",(0,r.jsxs)(n.p,{children:["As described in ",(0,r.jsx)(n.a,{href:"/docs/cad/expanders/",children:"CAD 009"}),", expanders MUST have at least ",(0,r.jsx)(n.code,{children:"{:expander true}"})," in their metadata."]}),"\n",(0,r.jsxs)(n.p,{children:["TODO. Use ",(0,r.jsx)(n.code,{children:":expander?"})," for consistency."]}),"\n",(0,r.jsx)(n.p,{children:"TODO. Example here? Or rather in CAD009?"}),"\n",(0,r.jsx)(n.p,{children:"TODO. Other sections besides documentation and expanders?"})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.