@codama/renderers-rust 1.2.6 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -392,6 +392,10 @@ var render = (template, context, options) => {
392
392
  env.addFilter("kebabCase", kebabCase);
393
393
  env.addFilter("titleCase", titleCase);
394
394
  env.addFilter("rustDocblock", rustDocblock);
395
+ env.addFilter("hasTrait", (traits, ...traitNames) => {
396
+ if (typeof traits !== "string") return false;
397
+ return traitNames.some((traitName) => traits.includes(traitName));
398
+ });
395
399
  return env.render(template, context);
396
400
  };
397
401
 
@@ -501,14 +505,51 @@ function extractFullyQualifiedNames(traits, imports) {
501
505
  return trait.slice(index + 2);
502
506
  });
503
507
  }
508
+ function getSerdeFieldAttribute(serdeWith, node, userOptions = {}) {
509
+ assertIsNode(node, ["accountNode", "definedTypeNode", "instructionNode"]);
510
+ const options = { ...DEFAULT_TRAIT_OPTIONS, ...userOptions };
511
+ const nodeType = getNodeType(node);
512
+ if (nodeType === "alias") {
513
+ return "";
514
+ }
515
+ const sanitizedOverrides = Object.fromEntries(
516
+ Object.entries(options.overrides).map(([key, value]) => [camelCase3(key), value])
517
+ );
518
+ const nodeOverrides = sanitizedOverrides[node.name];
519
+ const allTraits = nodeOverrides === void 0 ? getDefaultTraits(nodeType, options) : nodeOverrides;
520
+ const hasSerdeSerialize = allTraits.some((t) => t === "serde::Serialize" || t === "Serialize");
521
+ const hasSerdeDeserialize = allTraits.some((t) => t === "serde::Deserialize" || t === "Deserialize");
522
+ if (!hasSerdeSerialize && !hasSerdeDeserialize) {
523
+ return "";
524
+ }
525
+ const partitionedTraits = partitionTraitsInFeatures(allTraits, options.featureFlags);
526
+ const featuredTraits = partitionedTraits[1];
527
+ let serdeFeatureName;
528
+ for (const [feature, traits] of Object.entries(featuredTraits)) {
529
+ if (traits.some(
530
+ (t) => t === "serde::Serialize" || t === "serde::Deserialize" || t === "Serialize" || t === "Deserialize"
531
+ )) {
532
+ serdeFeatureName = feature;
533
+ break;
534
+ }
535
+ }
536
+ if (serdeFeatureName) {
537
+ return `#[cfg_attr(feature = "${serdeFeatureName}", serde(with = "${serdeWith}"))]
538
+ `;
539
+ } else {
540
+ return `#[serde(with = "${serdeWith}")]
541
+ `;
542
+ }
543
+ }
504
544
 
505
545
  // src/getTypeManifestVisitor.ts
506
546
  function getTypeManifestVisitor(options) {
507
- const { getImportFrom, getTraitsFromNode: getTraitsFromNode2 } = options;
547
+ const { getImportFrom, getTraitsFromNode: getTraitsFromNode2, traitOptions } = options;
508
548
  let parentName = options.parentName ?? null;
509
549
  let nestedStruct = options.nestedStruct ?? false;
510
550
  let inlineStruct = false;
511
551
  let parentSize = null;
552
+ let parentNode = null;
512
553
  return pipe(
513
554
  mergeVisitor(
514
555
  () => ({ imports: new ImportMap(), nestedStructs: [], type: "" }),
@@ -521,10 +562,12 @@ function getTypeManifestVisitor(options) {
521
562
  (v) => extendVisitor(v, {
522
563
  visitAccount(account, { self }) {
523
564
  parentName = pascalCase3(account.name);
565
+ parentNode = account;
524
566
  const manifest = visit3(account.data, self);
525
567
  const traits = getTraitsFromNode2(account);
526
568
  manifest.imports.mergeWith(traits.imports);
527
569
  parentName = null;
570
+ parentNode = null;
528
571
  return {
529
572
  ...manifest,
530
573
  type: traits.render + manifest.type
@@ -599,10 +642,12 @@ function getTypeManifestVisitor(options) {
599
642
  },
600
643
  visitDefinedType(definedType, { self }) {
601
644
  parentName = pascalCase3(definedType.name);
645
+ parentNode = definedType;
602
646
  const manifest = visit3(definedType.type, self);
603
647
  const traits = getTraitsFromNode2(definedType);
604
648
  manifest.imports.mergeWith(traits.imports);
605
649
  parentName = null;
650
+ parentNode = null;
606
651
  const renderedType = isNode4(definedType.type, ["enumTypeNode", "structTypeNode"]) ? manifest.type : `pub type ${pascalCase3(definedType.name)} = ${manifest.type};`;
607
652
  return { ...manifest, type: `${traits.render}${renderedType}` };
608
653
  },
@@ -649,10 +694,18 @@ function getTypeManifestVisitor(options) {
649
694
  const childManifest = visit3(enumTupleVariantType.tuple, self);
650
695
  parentName = originalParentName;
651
696
  let derive = "";
652
- if (childManifest.type === "(Pubkey)") {
653
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::DisplayFromStr>"))]\n';
654
- } else if (childManifest.type === "(Vec<Pubkey>)") {
655
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<Vec<serde_with::DisplayFromStr>>"))]\n';
697
+ if (parentNode && childManifest.type === "(Pubkey)") {
698
+ derive = getSerdeFieldAttribute(
699
+ "serde_with::As::<serde_with::DisplayFromStr>",
700
+ parentNode,
701
+ traitOptions
702
+ );
703
+ } else if (parentNode && childManifest.type === "(Vec<Pubkey>)") {
704
+ derive = getSerdeFieldAttribute(
705
+ "serde_with::As::<Vec<serde_with::DisplayFromStr>>",
706
+ parentNode,
707
+ traitOptions
708
+ );
656
709
  }
657
710
  return {
658
711
  ...childManifest,
@@ -799,14 +852,28 @@ ${variantNames}
799
852
  const docblock = rustDocblock(parseDocs(structFieldType.docs));
800
853
  const resolvedNestedType = resolveNestedTypeNode(structFieldType.type);
801
854
  let derive = "";
802
- if (fieldManifest.type === "Pubkey") {
803
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::DisplayFromStr>"))]\n';
804
- } else if (fieldManifest.type === "Vec<Pubkey>") {
805
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<Vec<serde_with::DisplayFromStr>>"))]\n';
806
- } else if (isNode4(resolvedNestedType, "arrayTypeNode") && isNode4(resolvedNestedType.count, "fixedCountNode") && resolvedNestedType.count.value > 32) {
807
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]\n';
808
- } else if (isNode4(resolvedNestedType, ["bytesTypeNode", "stringTypeNode"]) && isNode4(structFieldType.type, "fixedSizeTypeNode") && structFieldType.type.size > 32) {
809
- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::Bytes>"))]\n';
855
+ if (parentNode) {
856
+ if (fieldManifest.type === "Pubkey") {
857
+ derive = getSerdeFieldAttribute(
858
+ "serde_with::As::<serde_with::DisplayFromStr>",
859
+ parentNode,
860
+ traitOptions
861
+ );
862
+ } else if (fieldManifest.type === "Vec<Pubkey>") {
863
+ derive = getSerdeFieldAttribute(
864
+ "serde_with::As::<Vec<serde_with::DisplayFromStr>>",
865
+ parentNode,
866
+ traitOptions
867
+ );
868
+ } else if (isNode4(resolvedNestedType, "arrayTypeNode") && isNode4(resolvedNestedType.count, "fixedCountNode") && resolvedNestedType.count.value > 32) {
869
+ derive = getSerdeFieldAttribute("serde_big_array::BigArray", parentNode, traitOptions);
870
+ } else if (isNode4(resolvedNestedType, ["bytesTypeNode", "stringTypeNode"]) && isNode4(structFieldType.type, "fixedSizeTypeNode") && structFieldType.type.size > 32) {
871
+ derive = getSerdeFieldAttribute(
872
+ "serde_with::As::<serde_with::Bytes>",
873
+ parentNode,
874
+ traitOptions
875
+ );
876
+ }
810
877
  }
811
878
  return {
812
879
  ...fieldManifest,
@@ -879,7 +946,11 @@ function getRenderMapVisitor(options = {}) {
879
946
  const dependencyMap = options.dependencyMap ?? {};
880
947
  const getImportFrom = getImportFromFactory(options.linkOverrides ?? {});
881
948
  const getTraitsFromNode2 = getTraitsFromNodeFactory(options.traitOptions);
882
- const typeManifestVisitor = getTypeManifestVisitor({ getImportFrom, getTraitsFromNode: getTraitsFromNode2 });
949
+ const typeManifestVisitor = getTypeManifestVisitor({
950
+ getImportFrom,
951
+ getTraitsFromNode: getTraitsFromNode2,
952
+ traitOptions: options.traitOptions
953
+ });
883
954
  const anchorTraits = options.anchorTraits ?? true;
884
955
  return pipe2(
885
956
  staticVisitor(() => createRenderMap(), {
@@ -1102,8 +1173,13 @@ function renderVisitor(path, options = {}) {
1102
1173
  visit5(root, writeRenderMapVisitor(getRenderMapVisitor(options), path));
1103
1174
  if (options.formatCode) {
1104
1175
  if (options.crateFolder) {
1105
- const toolchain = options.toolchain ?? "+stable";
1106
- runFormatter("cargo", [toolchain, "fmt", "--manifest-path", `${options.crateFolder}/Cargo.toml`]);
1176
+ const removeFalsy = (arg) => Boolean(arg);
1177
+ runFormatter(
1178
+ "cargo",
1179
+ [options.toolchain, "fmt", "--manifest-path", `${options.crateFolder}/Cargo.toml`].filter(
1180
+ removeFalsy
1181
+ )
1182
+ );
1107
1183
  } else {
1108
1184
  logWarn2("No crate folder specified, skipping formatting.");
1109
1185
  }