GithubHelp home page GithubHelp logo

Comments (5)

Bas-Man avatar Bas-Man commented on August 15, 2024

I think I have found the cause of the issue.
The way I have implemented the following function

fn append_article_to_toml(&self, path: &Path) -> Result<()> {
        // Article zine.toml file must exist
        if !path.exists() {
            Err(anyhow::anyhow!("Issue toml file does not already exists"))?
        };

        let mut file = std::fs::OpenOptions::new().append(true).open(&path)?;

        let toml_str = toml::to_string(&self)?;

        // Code fix as the section does not appear to be added by default.
        file.write_all("[[article]]\n".as_bytes())?; 
        // This is the problem code is the line directly. 
        // I am adding this as it is for appending. But it breaks the toml parser in this test case.
        file.write_all(toml_str.as_bytes())?;

        Ok(())
    }

from zine.

Bas-Man avatar Bas-Man commented on August 15, 2024

Follow up question

Is there a special reason that you use

#[serde(skip_serializing, default)]

on

pub struct Issue {}

With this code my test case for has to be written as

#[test]
    fn test_append_article_to_issue() {
        let mut issue = Issue::default();
        let article = Article::new();
        let article2 = Article::new().set_title("my second article").finalize();
        issue.articles.push(article);
        issue.articles.push(article2);

        let mut toml_str = toml::to_string(&issue).unwrap();
        // if the skip can be removed the following for loop is not required and the complete
        // toml file can be written in a single function call
        for article in &issue.articles {
            toml_str.push_str("[[article]]\n");
            toml_str.push_str(toml::to_string::<Article>(&article).unwrap().as_str());
        }

        let issue_from_toml: Issue = toml::from_str(&toml_str).unwrap();
        assert_eq!(issue.slug, issue_from_toml.slug);
        assert_eq!(issue.articles[0].meta.file, "Give-this-file-a-name");
        assert_eq!(
            issue.articles[0].meta.file,
            issue_from_toml.articles[0].meta.file
        );

        assert_eq!(issue.articles[1].meta.file, "my-second-article");
        assert_eq!(
            issue.articles[1].meta.file,
            issue_from_toml.articles[1].meta.file
        );
    }

What are your thoughts @Folyd

from zine.

Folyd avatar Folyd commented on August 15, 2024

Do you mean this?

zine/src/entity/issue.rs

Lines 29 to 35 in c3e514b

/// Skip serialize `articles` since a single article page would
/// contain a issue context, the `articles` is useless for the
/// single article page.
#[serde(skip_serializing, default)]
#[serde(rename(deserialize = "article"))]
pub articles: Vec<Article>,
}

I have added a comment already, the main reason is we'll include the issue entity when render article, we skip articles to avoid unnecessary serialization, see:

zine/src/entity/issue.rs

Lines 108 to 127 in c3e514b

context.insert("issue", &self);
let articles = self
.articles
.iter()
// Only render article which need published.
.filter(|article| article.need_publish())
.collect::<Vec<_>>();
// Render articles with number context.
for (index, article) in articles.iter().enumerate() {
let mut context = context.clone();
context.insert("siblings", &self.sibling_articles(index));
context.insert("number", &(index + 1));
let dest = issue_dir.clone();
let article = (*article).clone();
tokio::task::spawn_blocking(move || {
article
.render(context, &dest)
.expect("Render article failed.");

from zine.

Bas-Man avatar Bas-Man commented on August 15, 2024

I might be missing something. But I don't think you are actually getting any benefit from this approach. I think it is actually creating more code. Doing this way means you have to manage [[article]] directly in code. See my code segment above.
This means you need to ensure that articles are added to the end of the issue's toml file using your own code logic. But without skip toml will handle it automatically.

The toml for an issue will always contain at least one article. And if it does not and the Vec<Article> is empty. Toml will correctly skip it by default.

from zine.

Bas-Man avatar Bas-Man commented on August 15, 2024

No longer needed.

from zine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.