erfars 0.2.0

Safe Rust bindings to the Essential Routines for Fundamental Astronomy (ERFA) C library.
Documentation
"""
Automatically parses the documentation comment from the ERFA source files and reformats them to Rust Markdown docstrings. Then, insert the formatted docstring into the appropriate Rust function

THE RUST FUNCTION MUST HAVE NO DOCSTRING AT ALL FOR THIS TO WORK
"""

import re
import textwrap

from comment_parser import comment_parser

ERFA_SRC = "https://github.com/liberfa/erfa/blob/master/src/"

files = sorted(
    [
        "ppsp.c",
        "epb.c",
        "gst06a.c",
        "pn.c",
        "s06.c",
        "p2pv.c",
        "tr.c",
        "pvdpv.c",
        "fave03.c",
        "pvu.c",
        "ry.c",
        "pnm06a.c",
        "fame03.c",
        "atciq.c",
        "aticqn.c",
        "apcg.c",
        "pnm80.c",
        "epb2jd.c",
        "h2fk5.c",
        "s00.c",
        "tttcg.c",
        "fal03.c",
        "fk45z.c",
        "ltp.c",
        "ee00b.c",
        "xys00b.c",
        "nut06a.c",
        "ppp.c",
        "pvtob.c",
        "s00a.c",
        "faju03.c",
        "tpxes.c",
        "gmst82.c",
        "pvstar.c",
        "pv2p.c",
        "rx.c",
        "pmat06.c",
        "pdp.c",
        "eqeq94.c",
        "ee00.c",
        "pmat76.c",
        "fane03.c",
        "obl80.c",
        "nutm80.c",
        "zpv.c",
        "pmat00.c",
        "d2dtf.c",
        "tf2a.c",
        "pm.c",
        "af2a.c",
        "ldn.c",
        "pn06.c",
        "s00b.c",
        "xy06.c",
        "starpm.c",
        "gmst06.c",
        "rxpv.c",
        "gst94.c",
        "hfk5z.c",
        "fw2xy.c",
        "zr.c",
        "dtdb.c",
        "atoc13.c",
        "xys06a.c",
        "atoi13.c",
        "ltecm.c",
        "moon98.c",
        "bpn2xy.c",
        "apco13.c",
        "ir.c",
        "dtf2d.c",
        "pxp.c",
        "tdbtcb.c",
        "t_erfa_c_extra.c",
        "gd2gc.c",
        "fk52h.c",
        "jdcalf.c",
        "ltpecl.c",
        "atoiq.c",
        "cal2jd.c",
        "ab.c",
        "p2s.c",
        "ee06a.c",
        "c2tpe.c",
        "s06a.c",
        "seps.c",
        "c2s.c",
        "num06a.c",
        "c2teqx.c",
        "fk425.c",
        "cpv.c",
        "rv2m.c",
        "pnm00a.c",
        "nut00b.c",
        "d2tf.c",
        "s2c.c",
        "apco.c",
        "pvmpv.c",
        "epv00.c",
        "tpxev.c",
        "pn06a.c",
        "ut1utc.c",
        "c2t00b.c",
        "rxr.c",
        "apcg13.c",
        "ld.c",
        "icrs2g.c",
        "tf2d.c",
        "fae03.c",
        "gst00b.c",
        "hd2pa.c",
        "atioq.c",
        "erfadatextra.c",
        "gst06.c",
        "pmsafe.c",
        "fk524.c",
        "pvxpv.c",
        "c2i00b.c",
        "pvm.c",
        "era00.c",
        "apcs13.c",
        "apci.c",
        "apio.c",
        "ut1tai.c",
        "tporv.c",
        "fasa03.c",
        "t_erfa_c.c",
        "ltpequ.c",
        "xys00a.c",
        "pnm00b.c",
        "nut00a.c",
        "prec76.c",
        "eform.c",
        "c2t00a.c",
        "ee00a.c",
        "s2pv.c",
        "apio13.c",
        "pb06.c",
        "c2t06a.c",
        "num00a.c",
        "aticq.c",
        "aper13.c",
        "faf03.c",
        "rm2v.c",
        "pr00.c",
        "apcs.c",
        "trxp.c",
        "fk5hz.c",
        "rxp.c",
        "num00b.c",
        "pap.c",
        "epj2jd.c",
        "sxp.c",
        "jd2cal.c",
        "faom03.c",
        "p06e.c",
        "sepp.c",
        "pn00.c",
        "sp00.c",
        "eceq06.c",
        "apci13.c",
        "lteqec.c",
        "ecm06.c",
        "c2ixys.c",
        "tttdb.c",
        "falp03.c",
        "pom00.c",
        "atciqn.c",
        "eors.c",
        "faur03.c",
        "ldsun.c",
        "eo06a.c",
        "eqec06.c",
        "atciqz.c",
        "fapa03.c",
        "fk5hip.c",
        "tcbtdb.c",
        "ae2hd.c",
        "lteceq.c",
        "atic13.c",
        "c2i00a.c",
        "numat.c",
        "taitt.c",
        "cr.c",
        "c2ibpn.c",
        "gc2gd.c",
        "ltpb.c",
        "ut1tt.c",
        "pfw06.c",
        "obl06.c",
        "g2icrs.c",
        "taiutc.c",
        "starpv.c",
        "gd2gce.c",
        "fk54z.c",
        "aper.c",
        "pn00a.c",
        "pvup.c",
        "pmpx.c",
        "tcgtt.c",
        "s2xpv.c",
        "hd2ae.c",
        "sxpv.c",
        "a2af.c",
        "atcc13.c",
        "utcut1.c",
        "c2i06a.c",
        "tttai.c",
        "c2tcio.c",
        "plan94.c",
        "a2tf.c",
        "tpsts.c",
        "fama03.c",
        "trxpv.c",
        "fad03.c",
        "taiut1.c",
        "bi00.c",
        "gc2gde.c",
        "s2p.c",
        "tdbtt.c",
        "atci13.c",
        "pn00b.c",
        "pv2s.c",
        "anpm.c",
        "tpstv.c",
        "atccq.c",
        "anp.c",
        "c2txy.c",
        "bp06.c",
        "ttut1.c",
        "zp.c",
        "nut80.c",
        "atco13.c",
        "bp00.c",
        "refco.c",
        "atio13.c",
        "pas.c",
        "gst00a.c",
        "cp.c",
        "pmp.c",
        "utctai.c",
        "epj.c",
        "gmst00.c",
        "rz.c",
        "tpors.c",
        "fw2m.c",
        "dat.c",
        "pvppv.c",
        "c2ixy.c",
        "eect00.c",
    ]
)

filepaths = ["../external/erfa/src/" + f for f in files]

docstrings = {}

for path, name in zip(filepaths, files):
    comments = comment_parser.extract_comments(path)
    doc_comment = comments[0].text()
    func_description = doc_comment.replace("**", "").split("\n\n")[1]
    cleaned_func_description = " ".join(func_description.split())
    as_md_docstring = textwrap.wrap(
        cleaned_func_description,
        width=80,
        initial_indent="/// ",
        subsequent_indent="/// ",
    )

    as_md_docstring.append("/// ")
    as_md_docstring.append(
        "/// Please see the full ERFA docs for this function [here]({})".format(
            ERFA_SRC + name
        )
    )

    docstrings[name] = "\n".join(as_md_docstring)
    print(f"DOCSTRING FOR {name}:\n")
    print(docstrings[name])
    print("")

rs_src_files = [
    "astrometry.rs",
    "calendar.rs",
    "eclipticcoordinates.rs",
    "ephemerides.rs",
    "fundamentalargs.rs",
    "galacticcoordinates.rs",
    "geodeticgeocentric.rs",
    "gnomonic.rs",
    "horizonequatorial.rs",
    "precnutpolar.rs",
    "rotationtime.rs",
    "spacemotion.rs",
    "starcatalogs.rs",
    "timescales.rs",
]

filepaths = ["../src/" + f for f in rs_src_files]

for path, name in zip(filepaths, rs_src_files):
    with open(path, "r") as file:
        contents = file.read()
        funcmatches = re.findall("pub fn \w*", contents)
        funcnames = [s.split()[2] for s in funcmatches]
        cfilenames = [s.lower() + ".c" for s in funcnames]
        print(cfilenames)
        for func, cfilename in zip(funcnames, cfilenames):
            contents = contents.replace(
                f"pub fn {func}(", f"{docstrings[cfilename]}\npub fn {func}("
            )

    with open(path, "w") as file:
        file.write(contents)